mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 19:34:43 +01:00
Compare commits
266
Commits
main
...
release/2.0.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6231be0ccf | ||
|
|
e93145a03b | ||
|
|
2cba368dc7 | ||
|
|
3ffc0e5501 | ||
|
|
2084588d37 | ||
|
|
5cb365cbc3 | ||
|
|
7999dfbecc | ||
|
|
e5a29c6d0f | ||
|
|
7e361f2c2c | ||
|
|
fd4e3b296b | ||
|
|
9e4ce4b5a4 | ||
|
|
923e104a79 | ||
|
|
1e82b1db2e | ||
|
|
deaac80afe | ||
|
|
3d375b00a6 | ||
|
|
7505ddf424 | ||
|
|
f8527f434d | ||
|
|
d348442dd3 | ||
|
|
64b0940b34 | ||
|
|
53734949b9 | ||
|
|
4cf5cbbc0a | ||
|
|
deec6a0fb7 | ||
|
|
5c3ba9b3e8 | ||
|
|
0954c037e5 | ||
|
|
de2912df02 | ||
|
|
db1138e173 | ||
|
|
fd350731e4 | ||
|
|
c48eb93caa | ||
|
|
307977af45 | ||
|
|
6ea0f35ef9 | ||
|
|
b95136fa5f | ||
|
|
c2b6948399 | ||
|
|
ca829154da | ||
|
|
1d42796c35 | ||
|
|
7cb7a494c2 | ||
|
|
76c9e1e512 | ||
|
|
c3542599fc | ||
|
|
07bd987367 | ||
|
|
d32d570ade | ||
|
|
c8685dc0d6 | ||
|
|
8c1db2c03c | ||
|
|
a953eeb1e2 | ||
|
|
2becb24f36 | ||
|
|
5a66b92cc5 | ||
|
|
dbf7448c09 | ||
|
|
3cab2fad20 | ||
|
|
04ed186359 | ||
|
|
1ebb3fabce | ||
|
|
a715808ea9 | ||
|
|
e986ddc1aa | ||
|
|
45412995f5 | ||
|
|
9aa01562d2 | ||
|
|
f8c4653079 | ||
|
|
137d510182 | ||
|
|
7f7d3a6052 | ||
|
|
2432ae550e | ||
|
|
ebd056a670 | ||
|
|
549e4bbf0a | ||
|
|
058b7cd54e | ||
|
|
918fe8e189 | ||
|
|
84f2a72520 | ||
|
|
490326ca77 | ||
|
|
e42b71082f | ||
|
|
dda09852db | ||
|
|
e4edf736f5 | ||
|
|
fd099a626d | ||
|
|
bcd73d85af | ||
|
|
5e38112e14 | ||
|
|
a744355b52 | ||
|
|
58e2647028 | ||
|
|
1ca252785b | ||
|
|
8f0e7e9106 | ||
|
|
5637e2e499 | ||
|
|
3d8432dd0b | ||
|
|
04a5cf5503 | ||
|
|
89e6d70bf5 | ||
|
|
405e6f21b0 | ||
|
|
144fe86e7f | ||
|
|
c177bdaf3b | ||
|
|
08e1e55438 | ||
|
|
db77f84198 | ||
|
|
6b0b06222b | ||
|
|
19e672d18e | ||
|
|
04da367e20 | ||
|
|
d4cfb1b73b | ||
|
|
0c7ef40fc0 | ||
|
|
4dd91a1871 | ||
|
|
bed3c393b9 | ||
|
|
7175562a53 | ||
|
|
dc284b7a4f | ||
|
|
a07f232d20 | ||
|
|
bcb30db6aa | ||
|
|
9935f85660 | ||
|
|
7fb1c91023 | ||
|
|
0dcdb81794 | ||
|
|
f25d807ffb | ||
|
|
5728d42fdc | ||
|
|
671f364999 | ||
|
|
51f219197b | ||
|
|
0b43cb79ac | ||
|
|
fdfe97c05a | ||
|
|
f818f378ed | ||
|
|
db89419f13 | ||
|
|
cf9de402a1 | ||
|
|
dda233c901 | ||
|
|
dad0af8563 | ||
|
|
c6353569ab | ||
|
|
5a767b1ab9 | ||
|
|
e85fef9e67 | ||
|
|
0375a036ea | ||
|
|
0000079e2a | ||
|
|
75a9df6be5 | ||
|
|
4abde2b285 | ||
|
|
ed653b2fd4 | ||
|
|
8c280359d9 | ||
|
|
1f88750add | ||
|
|
d340f17637 | ||
|
|
d39ddd3c80 | ||
|
|
90d7f5d9ec | ||
|
|
a984ac8cf8 | ||
|
|
e14171b72f | ||
|
|
357a5ff6a8 | ||
|
|
4c829cd4e5 | ||
|
|
b95df989cb | ||
|
|
99efb8ecad | ||
|
|
78f37fbd42 | ||
|
|
1175e3daca | ||
|
|
c34a55ff48 | ||
|
|
3658a65805 | ||
|
|
e680b4b413 | ||
|
|
aca4b089b2 | ||
|
|
60aa341a05 | ||
|
|
a2b366c009 | ||
|
|
22c05a3b3a | ||
|
|
4c09eee4d1 | ||
|
|
3ed2b6d7c6 | ||
|
|
2309664e17 | ||
|
|
2a9c9c187b | ||
|
|
e244a75e18 | ||
|
|
e76b609c1a | ||
|
|
5898dfb90a | ||
|
|
ccc6578e13 | ||
|
|
2fcfc897a2 | ||
|
|
95fcad56a6 | ||
|
|
fd84f6d661 | ||
|
|
4cec5c815a | ||
|
|
cdf254be43 | ||
|
|
405ce6a2da | ||
|
|
160b18f411 | ||
|
|
a9a6163be2 | ||
|
|
42ae59db47 | ||
|
|
ac134e7f3e | ||
|
|
7707c207a8 | ||
|
|
8a40369330 | ||
|
|
7f625555c7 | ||
|
|
684ddf7108 | ||
|
|
bc4311e84b | ||
|
|
726a85cdaf | ||
|
|
59435542b2 | ||
|
|
73accaf7a3 | ||
|
|
78ec831580 | ||
|
|
1b9e26a6e9 | ||
|
|
c0e98bd1d4 | ||
|
|
f00d1ec76e | ||
|
|
5ef35bb3b9 | ||
|
|
1cc7123c31 | ||
|
|
10bf473795 | ||
|
|
0c8694c692 | ||
|
|
ca190dbd19 | ||
|
|
42b7a9db52 | ||
|
|
d5ee0731d9 | ||
|
|
aeab3da31c | ||
|
|
780a8f52f2 | ||
|
|
e9a590aacb | ||
|
|
88bd893637 | ||
|
|
e9b9c677dc | ||
|
|
7658c468a8 | ||
|
|
b12c02b4a0 | ||
|
|
092f0e8dbf | ||
|
|
52bc971cee | ||
|
|
77cf4153a4 | ||
|
|
86201d7cbc | ||
|
|
5b0bb4f2fb | ||
|
|
06ff5565f1 | ||
|
|
51a7e5d66b | ||
|
|
1277551b73 | ||
|
|
268167ad7f | ||
|
|
f4d6b21a21 | ||
|
|
74cf373f70 | ||
|
|
13d5449a5a | ||
|
|
3ab30975ab | ||
|
|
72ea2524f2 | ||
|
|
d5ff0160a3 | ||
|
|
50238688d2 | ||
|
|
486744a8cb | ||
|
|
2eb8d9ae0e | ||
|
|
3ca2c94b23 | ||
|
|
435ff82566 | ||
|
|
1a2f440027 | ||
|
|
bec2f6d559 | ||
|
|
a72256e27c | ||
|
|
1f93967a35 | ||
|
|
2fcee4b77d | ||
|
|
efd5d7a883 | ||
|
|
5b93e5a79f | ||
|
|
c1e4c7b8ea | ||
|
|
c1000aedc8 | ||
|
|
a851117858 | ||
|
|
94ffc85f7c | ||
|
|
e1aeeb6335 | ||
|
|
3c6c393215 | ||
|
|
f715a1c4d1 | ||
|
|
ea65c15f05 | ||
|
|
e47e2352a5 | ||
|
|
d88e9279ec | ||
|
|
1823eba540 | ||
|
|
6d71770be9 | ||
|
|
f48b388e87 | ||
|
|
c8730fef90 | ||
|
|
010a415fc0 | ||
|
|
4acece4488 | ||
|
|
cd6b1a76a3 | ||
|
|
e1e9a248cc | ||
|
|
2cb897f8d2 | ||
|
|
c86ed53b64 | ||
|
|
c24c54122d | ||
|
|
2da87bfe5c | ||
|
|
12d691d2fc | ||
|
|
6597a49963 | ||
|
|
1a4a02dd25 | ||
|
|
e85818e856 | ||
|
|
f6a1a02519 | ||
|
|
b06e6090fe | ||
|
|
d27fbecbb5 | ||
|
|
a1aac37c1d | ||
|
|
52f0a7b36b | ||
|
|
bac60c9403 | ||
|
|
3701acaa08 | ||
|
|
d841c1c227 | ||
|
|
40d06d6ddb | ||
|
|
4967a787f3 | ||
|
|
28e662e098 | ||
|
|
c75d34e204 | ||
|
|
b7955d3b9a | ||
|
|
ae238e09c7 | ||
|
|
83403ac936 | ||
|
|
e0a91a2e65 | ||
|
|
222a3b36f1 | ||
|
|
b40cdd5152 | ||
|
|
4802edaa70 | ||
|
|
38fe07725a | ||
|
|
03304d188e | ||
|
|
636c5243cc | ||
|
|
f65f624fba | ||
|
|
785b5a7d6e | ||
|
|
79c47443bf | ||
|
|
de1aa089a7 | ||
|
|
d7b28ad0c2 | ||
|
|
bf11f5f9f5 | ||
|
|
3ff3a8c624 | ||
|
|
187ddd8518 | ||
|
|
fc6b8c5482 | ||
|
|
800a1226ae | ||
|
|
e05ffc482b | ||
|
|
6b921358af | ||
|
|
9347db3509 |
No files matched your search
-49
@@ -1,49 +0,0 @@
|
||||
$Id$
|
||||
|
||||
This file lists hardware, which doesn't do what it should do.
|
||||
|
||||
Due to the nature of FreeBSD, we do not have the resources to test all
|
||||
possible kinds of hardware. We do however every now and then find, buy
|
||||
or hear about hardware which doesn't work with FreeBSD or in general.
|
||||
|
||||
This is that list.
|
||||
|
||||
To be added to this list, a piece of hardware has to:
|
||||
A: not do what it claims.
|
||||
or
|
||||
B: not do what common sense would expect it to.
|
||||
|
||||
Only if performance claims are wildly of the mark will it be listed here.
|
||||
|
||||
All entries must have a date and a mail-address associated with them, to
|
||||
reflect when and by whom they were added.
|
||||
For multifunctional devices, please indicate if other parts of the device
|
||||
work OK, or are untested.
|
||||
For mutual incompabilities, list both devices.
|
||||
For SCSI and IDE-devices, list the string seen on boot of FreeBSD, if
|
||||
possible, and trade name.
|
||||
Infer format from other entries, Keep sorted by first line.
|
||||
|
||||
Thankyou.
|
||||
|
||||
---
|
||||
Controller, Data Technology DTC2280, "PC/AT Super I/O Card"
|
||||
IDE interface can be set to secondary address, but doesn't work there. Suspect
|
||||
Interrupt isn't moved along. Works fine on primary address. Other parts of
|
||||
card not tested.
|
||||
19940828 [email protected]
|
||||
---
|
||||
IDE-disk, <Maxtor 7345 AT>, "Maxtor 7345"
|
||||
Cannot coexist on the same IDE-controller with a <WDC AC2540H>, "Western
|
||||
Digital Caviar 2540" disk. Jumpers not exhaustively experimented with, as
|
||||
neither of the companies make sufficient information available. Disk works
|
||||
fine when alone on IDE-controller.
|
||||
19940828 [email protected]
|
||||
---
|
||||
IDE-disk, <WDC AC2540H>, "Western Digital Caviar 2540"
|
||||
Cannot coexist on the same IDE-controller with a <Maxtor 7345 AT>, "Maxtor
|
||||
7345" disk. Jumpers not exhaustively experimented with, as neither of the
|
||||
companies make sufficient information available. Disk works fine when alone
|
||||
on IDE-controller.
|
||||
19940828 [email protected]
|
||||
---
|
||||
@@ -1,7 +0,0 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
PROG= chflags
|
||||
SRCS= chflags.c stat_flags.c
|
||||
.PATH: ${.CURDIR}/../../bin/ls
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,125 +0,0 @@
|
||||
.\" Copyright (c) 1989, 1990, 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)chflags.1 8.2 (Berkeley) 3/31/94
|
||||
.\"
|
||||
.Dd March 31, 1994
|
||||
.Dt CHFLAGS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm chflags
|
||||
.Nd change file flags
|
||||
.Sh SYNOPSIS
|
||||
.Nm chflags
|
||||
.Oo
|
||||
.Fl R
|
||||
.Op Fl H | Fl L | Fl P
|
||||
.Oc
|
||||
.Ar flags
|
||||
.Ar file ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm chflags
|
||||
utility modifies the file flags of the listed files
|
||||
as specified by the
|
||||
.Ar flags
|
||||
operand.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl H
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, symbolic links on the command line are followed.
|
||||
(Symbolic links encountered in the tree traversal are not followed.)
|
||||
.It Fl L
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, all symbolic links are followed.
|
||||
.It Fl P
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, no symbolic links are followed.
|
||||
.It Fl R
|
||||
Change the file flags for the file hierarchies rooted
|
||||
in the files instead of just the files themselves.
|
||||
.El
|
||||
.Pp
|
||||
Flags are a comma separated list of keywords.
|
||||
The following keywords are currently defined:
|
||||
.Bd -literal -offset indent compact
|
||||
arch set the archived flag (super-user only)
|
||||
dump set the dump flag
|
||||
sappnd set the system append-only flag (super-user only)
|
||||
schg set the system immutable flag (super-user only)
|
||||
uappnd set the user append-only flag (owner or super-user only)
|
||||
uchg set the user immutable flag (owner or super-user only)
|
||||
archived, sappend, schange, simmutable, uappend, uchange, uimmutable
|
||||
aliases for the above
|
||||
.Ed
|
||||
.Pp
|
||||
Putting the letters
|
||||
.Dq no
|
||||
before an option causes the flag to be turned off.
|
||||
For example:
|
||||
.Bd -literal -offset indent compact
|
||||
nodump the file should never be dumped
|
||||
.Ed
|
||||
.Pp
|
||||
Symbolic links do not have flags, so unless the
|
||||
.Fl H
|
||||
or
|
||||
.Fl L
|
||||
option is set,
|
||||
.Nm chflags
|
||||
on a symbolic link always succeeds and has no effect.
|
||||
The
|
||||
.Fl H ,
|
||||
.Fl L
|
||||
and
|
||||
.Fl P
|
||||
options are ignored unless the
|
||||
.Fl R
|
||||
option is specified.
|
||||
In addition, these options override each other and the
|
||||
command's actions are determined by the last one specified.
|
||||
.Pp
|
||||
The
|
||||
.Nm chflags
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh SEE ALSO
|
||||
.Xr chflags 2 ,
|
||||
.Xr stat 2 ,
|
||||
.Xr fts 3 ,
|
||||
.Xr symlink 7
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1992, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)chflags.c 8.5 (Berkeley) 4/1/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fts.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
u_long string_to_flags __P((char **, u_long *, u_long *));
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
FTS *ftsp;
|
||||
FTSENT *p;
|
||||
u_long clear, set;
|
||||
long val;
|
||||
int Hflag, Lflag, Pflag, Rflag, ch, fts_options, oct, rval;
|
||||
char *flags, *ep;
|
||||
|
||||
Hflag = Lflag = Pflag = Rflag = 0;
|
||||
while ((ch = getopt(argc, argv, "HLPR")) != EOF)
|
||||
switch (ch) {
|
||||
case 'H':
|
||||
Hflag = 1;
|
||||
Lflag = Pflag = 0;
|
||||
break;
|
||||
case 'L':
|
||||
Lflag = 1;
|
||||
Hflag = Pflag = 0;
|
||||
break;
|
||||
case 'P':
|
||||
Pflag = 1;
|
||||
Hflag = Lflag = 0;
|
||||
break;
|
||||
case 'R':
|
||||
Rflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
fts_options = FTS_PHYSICAL;
|
||||
if (Rflag) {
|
||||
if (Hflag)
|
||||
fts_options |= FTS_COMFOLLOW;
|
||||
if (Lflag) {
|
||||
fts_options &= ~FTS_PHYSICAL;
|
||||
fts_options |= FTS_LOGICAL;
|
||||
}
|
||||
}
|
||||
|
||||
flags = *argv;
|
||||
if (*flags >= '0' && *flags <= '7') {
|
||||
errno = 0;
|
||||
val = strtol(flags, &ep, 8);
|
||||
if (val < 0)
|
||||
errno = ERANGE;
|
||||
if (errno)
|
||||
err(1, "invalid flags: %s", flags);
|
||||
if (*ep)
|
||||
errx(1, "invalid flags: %s", flags);
|
||||
set = val;
|
||||
oct = 1;
|
||||
} else {
|
||||
if (string_to_flags(&flags, &set, &clear))
|
||||
errx(1, "invalid flag: %s", flags);
|
||||
clear = ~clear;
|
||||
oct = 0;
|
||||
}
|
||||
|
||||
if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
|
||||
switch (p->fts_info) {
|
||||
case FTS_D:
|
||||
if (Rflag) /* Change it at FTS_DP. */
|
||||
continue;
|
||||
fts_set(ftsp, p, FTS_SKIP);
|
||||
break;
|
||||
case FTS_DNR: /* Warn, chflag, continue. */
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
break;
|
||||
case FTS_ERR: /* Warn, continue. */
|
||||
case FTS_NS:
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
continue;
|
||||
case FTS_SL: /* Ignore. */
|
||||
case FTS_SLNONE:
|
||||
/*
|
||||
* The only symlinks that end up here are ones that
|
||||
* don't point to anything and ones that we found
|
||||
* doing a physical walk.
|
||||
*/
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (oct) {
|
||||
if (!chflags(p->fts_accpath, set))
|
||||
continue;
|
||||
} else {
|
||||
p->fts_statp->st_flags |= set;
|
||||
p->fts_statp->st_flags &= clear;
|
||||
if (!chflags(p->fts_accpath, p->fts_statp->st_flags))
|
||||
continue;
|
||||
}
|
||||
warn("%s", p->fts_path);
|
||||
rval = 1;
|
||||
}
|
||||
if (errno)
|
||||
err(1, "fts_read");
|
||||
exit(rval);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: chflags [-R [-H | -L | -P]] flags file ...\n");
|
||||
exit(1);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
+20
-17
@@ -1,5 +1,5 @@
|
||||
# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
|
||||
# $Id: Makefile,v 1.10 1995/01/20 22:40:02 wollman Exp $
|
||||
# $Id: Makefile,v 1.11 1995/02/11 18:25:38 ache Exp $
|
||||
|
||||
SUBDIR= include des acl kdb krb libkadm
|
||||
|
||||
@@ -12,22 +12,26 @@ SUBDIR+= ext_srvtab kdb_destroy kdb_edit \
|
||||
|
||||
SDIR= ${.CURDIR}/..
|
||||
|
||||
CODAI?= ${MAKE} ${MFLAGS} cleandir; \
|
||||
${MAKE} ${MFLAGS} obj; ${MAKE} ${MFLAGS} depend all install
|
||||
CODAI= ${MAKE} ${MFLAGS} cleandir; \
|
||||
${MAKE} ${MFLAGS} obj; \
|
||||
${MAKE} ${MFLAGS} depend all install
|
||||
|
||||
CODAD= ${MAKE} ${MFLAGS} MAKE_EBONES=yes cleandir; \
|
||||
${MAKE} ${MFLAGS} MAKE_EBONES=yes obj; \
|
||||
${MAKE} ${MFLAGS} MAKE_EBONES=yes depend all distribute
|
||||
|
||||
# These are the programs which depend on kerberos
|
||||
# It's nice to know who they are
|
||||
kprog:
|
||||
cd ${SDIR}/bin/rcp; ${CODAI}
|
||||
cd ${SDIR}/libexec/rlogind; ${CODAI}
|
||||
cd ${SDIR}/libexec/rshd; ${CODAI}
|
||||
cd ${SDIR}/sbin/mount_nfs; ${CODAI}
|
||||
cd ${SDIR}/sbin/nfsd; ${CODAI}
|
||||
cd ${SDIR}/usr.bin/login; ${CODAI}
|
||||
cd ${SDIR}/usr.bin/passwd; ${CODAI}
|
||||
cd ${SDIR}/usr.bin/rlogin; ${CODAI}
|
||||
cd ${SDIR}/usr.bin/rsh; ${CODAI}
|
||||
cd ${SDIR}/usr.bin/su; ${CODAI}
|
||||
cd ${SDIR}/usr.bin/passwd; ${CODAI}
|
||||
cd ${SDIR}/libexec/kpasswdd; ${CODAI}
|
||||
|
||||
bootstrap:
|
||||
cd include; ${MAKE} ${MFLAGS} install
|
||||
@@ -40,17 +44,16 @@ bootstrap:
|
||||
${MAKE} ${MFLAGS} depend all install kprog
|
||||
|
||||
help-distribute: distribute
|
||||
cd ${SDIR}/bin/rcp; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/libexec/rlogind; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/libexec/rshd; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/usr.bin/login; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/usr.bin/passwd; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/usr.bin/rlogin; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/usr.bin/rsh; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/usr.bin/su; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/usr.bin/passwd; ${MAKE} ${MFLAGS} distribute
|
||||
cd ${SDIR}/libexec/kpasswdd; ${MAKE} ${MFLAGS} distribute
|
||||
|
||||
cd ${SDIR}/bin/rcp; ${CODAD}
|
||||
cd ${SDIR}/libexec/rlogind; ${CODAD}
|
||||
cd ${SDIR}/libexec/rshd; ${CODAD}
|
||||
cd ${SDIR}/sbin/mount_nfs; ${CODAD}
|
||||
cd ${SDIR}/sbin/nfsd; ${CODAD}
|
||||
cd ${SDIR}/usr.bin/login; ${CODAD}
|
||||
cd ${SDIR}/usr.bin/passwd; ${CODAD}
|
||||
cd ${SDIR}/usr.bin/rlogin; ${CODAD}
|
||||
cd ${SDIR}/usr.bin/rsh; ${CODAD}
|
||||
cd ${SDIR}/usr.bin/su; ${CODAD}
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
|
||||
# $Id: Makefile,v 1.2 1994/07/19 19:21:23 g89r4222 Exp $
|
||||
|
||||
PROG= compile_et
|
||||
CFLAGS+=-I. -I${.CURDIR}
|
||||
SRCS= compile_et.c error_message.c et_name.c init_et.c perror.c
|
||||
OBJS+= error_table.o
|
||||
DPADD= ${LIBL}
|
||||
LDADD= -ll
|
||||
CLEANFILES=et_lex.lex.c y.tab.c y.tab.h error_table.c
|
||||
NOMAN= noman
|
||||
|
||||
error_table.c: et_lex.lex.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 1986, 1987 by MIT Student Information Processing Board
|
||||
* For copyright info, see "Copyright.SIPB".
|
||||
*
|
||||
* $Id: compile_et.c,v 1.2 1994/07/19 19:21:24 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/file.h>
|
||||
#include <strings.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
|
||||
|
||||
extern char *gensym();
|
||||
extern char *current_token;
|
||||
extern int table_number, current;
|
||||
char buffer[BUFSIZ];
|
||||
char *table_name = (char *)NULL;
|
||||
FILE *hfile, *cfile;
|
||||
|
||||
/* C library */
|
||||
extern char *malloc();
|
||||
extern int errno;
|
||||
|
||||
/* lex stuff */
|
||||
extern FILE *yyin;
|
||||
extern int yylineno;
|
||||
|
||||
/* pathnames */
|
||||
char c_file[MAXPATHLEN]; /* temporary file */
|
||||
char h_file[MAXPATHLEN]; /* output */
|
||||
char o_file[MAXPATHLEN]; /* output */
|
||||
char et_file[MAXPATHLEN]; /* input */
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register char *p;
|
||||
int n_flag = 0, debug = 0;
|
||||
|
||||
while (argc > 2) {
|
||||
register char *arg, ch;
|
||||
arg = argv[--argc];
|
||||
if (strlen(arg) != 2 || arg[0] != '-')
|
||||
goto usage;
|
||||
ch = arg[1];
|
||||
if (ch == 'n')
|
||||
n_flag++;
|
||||
else if (ch == 'd')
|
||||
debug++;
|
||||
else
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if (argc != 2) {
|
||||
usage:
|
||||
fprintf(stderr, "Usage: %s et_file [-n]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
strcpy(et_file, argv[1]);
|
||||
p = rindex(et_file, '/');
|
||||
if (p == (char *)NULL)
|
||||
p = et_file;
|
||||
else
|
||||
p++;
|
||||
p = rindex(p, '.');
|
||||
if (!strcmp(p, ".et"))
|
||||
*++p = '\0';
|
||||
else {
|
||||
if (!p)
|
||||
p = et_file;
|
||||
while (*p)
|
||||
p++;
|
||||
*p++ = '.';
|
||||
*p = '\0';
|
||||
}
|
||||
/* p points at null where suffix should be */
|
||||
strcpy(p, "et.c");
|
||||
strcpy(c_file, et_file);
|
||||
p[0] = 'h';
|
||||
p[1] = '\0';
|
||||
strcpy(h_file, et_file);
|
||||
p[0] = 'o';
|
||||
strcpy(o_file, et_file);
|
||||
p[0] = 'e';
|
||||
p[1] = 't';
|
||||
p[2] = '\0';
|
||||
|
||||
yyin = fopen(et_file, "r");
|
||||
if (!yyin) {
|
||||
perror(et_file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
hfile = fopen(h_file, "w");
|
||||
if (hfile == (FILE *)NULL) {
|
||||
perror(h_file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cfile = fopen(c_file, "w");
|
||||
if (cfile == (FILE *)NULL) {
|
||||
perror("Can't open temp file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* parse it */
|
||||
fputs("#define NULL 0\n", cfile);
|
||||
fputs("static char *_et[] = {\n", cfile);
|
||||
|
||||
yyparse();
|
||||
fclose(yyin); /* bye bye input file */
|
||||
|
||||
fputs("\t(char *)0\n};\n", cfile);
|
||||
fputs("extern int init_error_table();\n\n", cfile);
|
||||
fprintf(cfile, "int %s_err_base = %d;\n\n", table_name, table_number);
|
||||
fprintf(cfile, "int\ninit_%s_err_tbl()\n", table_name);
|
||||
fprintf(cfile, "{\n\treturn(init_error_table(_et, %d, %d));\n}\n",
|
||||
table_number, current);
|
||||
fclose(cfile);
|
||||
|
||||
fputs("extern int init_", hfile);
|
||||
fputs(table_name, hfile);
|
||||
fputs("_err_tbl();\nextern int ", hfile);
|
||||
fputs(table_name, hfile);
|
||||
fputs("_err_base;\n", hfile);
|
||||
fclose(hfile); /* bye bye hfile */
|
||||
|
||||
if (n_flag)
|
||||
exit(0);
|
||||
|
||||
if (!fork()) {
|
||||
p = rindex(c_file, '/');
|
||||
if (p) {
|
||||
*p++ = '\0';
|
||||
chdir(c_file);
|
||||
}
|
||||
else
|
||||
p = c_file;
|
||||
execlp("cc", "cc", "-c", "-R", "-O", p, 0);
|
||||
perror("cc");
|
||||
exit(1);
|
||||
}
|
||||
else wait(0);
|
||||
|
||||
if (!debug)
|
||||
(void) unlink(c_file);
|
||||
/* make it .o file name */
|
||||
c_file[strlen(c_file)-1] = 'o';
|
||||
if (!fork()) {
|
||||
execlp("cp", "cp", c_file, o_file, 0);
|
||||
perror("cp");
|
||||
exit(1);
|
||||
}
|
||||
else wait(0);
|
||||
if (!debug)
|
||||
(void) unlink(c_file);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
yyerror(s)
|
||||
char *s;
|
||||
{
|
||||
fputs(s, stderr);
|
||||
fprintf(stderr, "\nLine number %d; last token was '%s'\n",
|
||||
yylineno, current_token);
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987 by the Student Information Processing Board
|
||||
* of the Massachusetts Institute of Technology
|
||||
* For copyright info, see "Copyright.SIPB".
|
||||
*
|
||||
* from: error_message.c,v 1.1 86/11/10 21:34:34 spook Exp $
|
||||
* $Id: error_message.c,v 1.3 1994/09/09 21:43:22 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "error_table.h"
|
||||
extern int sys_nerr;
|
||||
|
||||
static char buffer[25];
|
||||
|
||||
char *
|
||||
error_message(code)
|
||||
int code;
|
||||
{
|
||||
register int offset;
|
||||
register error_table **et;
|
||||
register int table_num;
|
||||
register int div;
|
||||
register char *cp;
|
||||
|
||||
offset = code & ((1<<ERRCODE_RANGE)-1);
|
||||
table_num = code - offset;
|
||||
if ((_et_list == (error_table **)NULL) && table_num)
|
||||
goto oops;
|
||||
if (!table_num) {
|
||||
if (offset < sys_nerr)
|
||||
return(sys_errlist[offset]);
|
||||
else
|
||||
goto oops;
|
||||
}
|
||||
for (et = _et_list; *et != (error_table *)NULL; et++) {
|
||||
if ((*et)->base == table_num) {
|
||||
/* This is the right table */
|
||||
if ((*et)->n_msgs <= offset)
|
||||
goto oops;
|
||||
return((*et)->msgs[offset]);
|
||||
}
|
||||
}
|
||||
oops:
|
||||
cp = buffer;
|
||||
{
|
||||
register char *cp1;
|
||||
for (cp1 = "Unknown code "; *cp1; cp1++, cp++)
|
||||
*cp = *cp1;
|
||||
if (table_num) {
|
||||
for (cp1 = error_table_name(table_num); *cp1; cp1++, cp++)
|
||||
*cp = *cp1;
|
||||
*cp++ = ' ';
|
||||
*cp = '\0';
|
||||
}
|
||||
}
|
||||
div = 1000000000;
|
||||
if (offset == 0) {
|
||||
*cp++ = '0';
|
||||
*cp = '\0';
|
||||
return(buffer);
|
||||
}
|
||||
while (div > offset)
|
||||
div /= 10;
|
||||
do {
|
||||
register int n = offset / div;
|
||||
*cp++ = '0' + n;
|
||||
offset -= n * div;
|
||||
div /= 10;
|
||||
} while (offset && div);
|
||||
while (div) {
|
||||
*cp++ = '0';
|
||||
div /= 10;
|
||||
}
|
||||
*cp = '\0';
|
||||
return(buffer);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef _ET
|
||||
extern int errno;
|
||||
typedef struct {
|
||||
char **msgs;
|
||||
int base;
|
||||
int n_msgs;
|
||||
} error_table;
|
||||
extern error_table **_et_list;
|
||||
|
||||
#define ERROR_CODE "int" /* type used for error codes */
|
||||
|
||||
#define ERRCODE_RANGE 8 /* # of bits to shift table number */
|
||||
#define BITS_PER_CHAR 6 /* # bits to shift per character in name */
|
||||
|
||||
extern char *error_table_name();
|
||||
#define _ET
|
||||
#endif
|
||||
@@ -1,205 +0,0 @@
|
||||
%{
|
||||
#include <stdio.h>
|
||||
char *str_concat(), *ds(), *quote(), *malloc(), *realloc();
|
||||
char *current_token = (char *)NULL;
|
||||
extern char *table_name;
|
||||
%}
|
||||
%union {
|
||||
char *dynstr;
|
||||
}
|
||||
|
||||
%token ERROR_TABLE ERROR_CODE_ENTRY END
|
||||
%token <dynstr> STRING QUOTED_STRING
|
||||
%type <dynstr> ec_name description table_id
|
||||
%{
|
||||
%}
|
||||
%start error_table
|
||||
%%
|
||||
|
||||
error_table : ERROR_TABLE table_id error_codes END
|
||||
{ table_name = ds($2);
|
||||
current_token = table_name;
|
||||
put_ecs(); }
|
||||
;
|
||||
|
||||
table_id : STRING
|
||||
{ current_token = $1;
|
||||
set_table_num($1);
|
||||
$$ = $1; }
|
||||
;
|
||||
|
||||
error_codes : error_codes ec_entry
|
||||
| ec_entry
|
||||
;
|
||||
|
||||
ec_entry : ERROR_CODE_ENTRY ec_name ',' description
|
||||
{ add_ec($2, $4);
|
||||
free($2);
|
||||
free($4); }
|
||||
| ERROR_CODE_ENTRY ec_name '=' STRING ',' description
|
||||
{ add_ec_val($2, $4, $6);
|
||||
free($2);
|
||||
free($4);
|
||||
free($6);
|
||||
}
|
||||
;
|
||||
|
||||
ec_name : STRING
|
||||
{ $$ = ds($1);
|
||||
current_token = $$; }
|
||||
;
|
||||
|
||||
description : QUOTED_STRING
|
||||
{ $$ = ds($1);
|
||||
current_token = $$; }
|
||||
;
|
||||
|
||||
%%
|
||||
/*
|
||||
* Copyright 1986, 1987 by the MIT Student Information Processing Board
|
||||
* For copyright info, see Copyright.SIPB.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include "error_table.h"
|
||||
|
||||
extern FILE *hfile, *cfile;
|
||||
|
||||
static long gensym_n = 0;
|
||||
char *
|
||||
gensym(x)
|
||||
char *x;
|
||||
{
|
||||
char *symbol;
|
||||
if (!gensym_n) {
|
||||
struct timeval tv;
|
||||
struct timezone tzp;
|
||||
gettimeofday(&tv, &tzp);
|
||||
gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000;
|
||||
}
|
||||
symbol = malloc(32 * sizeof(char));
|
||||
gensym_n++;
|
||||
sprintf(symbol, "et%ld", gensym_n);
|
||||
return(symbol);
|
||||
}
|
||||
|
||||
char *
|
||||
ds(string)
|
||||
char *string;
|
||||
{
|
||||
char *rv;
|
||||
rv = malloc(strlen(string)+1);
|
||||
strcpy(rv, string);
|
||||
return(rv);
|
||||
}
|
||||
|
||||
char *
|
||||
quote(string)
|
||||
char *string;
|
||||
{
|
||||
char *rv;
|
||||
rv = malloc(strlen(string)+3);
|
||||
strcpy(rv, "\"");
|
||||
strcat(rv, string);
|
||||
strcat(rv, "\"");
|
||||
return(rv);
|
||||
}
|
||||
|
||||
int table_number;
|
||||
int current = 0;
|
||||
char **error_codes = (char **)NULL;
|
||||
|
||||
add_ec(name, description)
|
||||
char *name, *description;
|
||||
{
|
||||
fprintf(cfile, "\t\"%s\",\n", description);
|
||||
if (error_codes == (char **)NULL) {
|
||||
error_codes = (char **)malloc(sizeof(char *));
|
||||
*error_codes = (char *)NULL;
|
||||
}
|
||||
error_codes = (char **)realloc((char *)error_codes,
|
||||
(current + 2)*sizeof(char *));
|
||||
error_codes[current++] = ds(name);
|
||||
error_codes[current] = (char *)NULL;
|
||||
}
|
||||
|
||||
add_ec_val(name, val, description)
|
||||
char *name, *val, *description;
|
||||
{
|
||||
int ncurrent = atoi(val);
|
||||
if (ncurrent < current) {
|
||||
printf("Error code %s (%d) out of order", name,
|
||||
current);
|
||||
return;
|
||||
}
|
||||
|
||||
while (ncurrent > current)
|
||||
fputs("\t(char *)NULL,\n", cfile), current++;
|
||||
|
||||
fprintf(cfile, "\t\"%s\",\n", description);
|
||||
if (error_codes == (char **)NULL) {
|
||||
error_codes = (char **)malloc(sizeof(char *));
|
||||
*error_codes = (char *)NULL;
|
||||
}
|
||||
error_codes = (char **)realloc((char *)error_codes,
|
||||
(current + 2)*sizeof(char *));
|
||||
error_codes[current++] = ds(name);
|
||||
error_codes[current] = (char *)NULL;
|
||||
}
|
||||
|
||||
put_ecs()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < current; i++) {
|
||||
if (error_codes[i] != (char *)NULL)
|
||||
fprintf(hfile, "#define %-40s ((%s)%d)\n",
|
||||
error_codes[i], ERROR_CODE, table_number + i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* char_to_num -- maps letters and numbers into a small numbering space
|
||||
* uppercase -> 1-26
|
||||
* lowercase -> 27-52
|
||||
* digits -> 53-62
|
||||
* underscore-> 63
|
||||
*/
|
||||
int
|
||||
char_to_num(c)
|
||||
char c;
|
||||
{
|
||||
if (isupper(c))
|
||||
return(c-'A'+1);
|
||||
else if (islower(c))
|
||||
return(c-'a'+27);
|
||||
else if (isdigit(c))
|
||||
return(c-'0'+53);
|
||||
else {
|
||||
fprintf(stderr, "Illegal character in name: %c\n", c);
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
set_table_num(string)
|
||||
char *string;
|
||||
{
|
||||
if (strlen(string) > 4) {
|
||||
fprintf(stderr, "Table name %s too long, truncated ",
|
||||
string);
|
||||
string[4] = '\0';
|
||||
fprintf(stderr, "to %s\n", string);
|
||||
}
|
||||
while (*string != '\0') {
|
||||
table_number = (table_number << BITS_PER_CHAR)
|
||||
+ char_to_num(*string);
|
||||
string++;
|
||||
}
|
||||
table_number = table_number << ERRCODE_RANGE;
|
||||
}
|
||||
|
||||
#include "et_lex.lex.c"
|
||||
@@ -1,29 +0,0 @@
|
||||
%{
|
||||
extern int yylineno;
|
||||
int yylineno = 1;
|
||||
%}
|
||||
|
||||
PC [^\"\n]
|
||||
AN [A-Z_a-z0-9]
|
||||
%%
|
||||
|
||||
error_table return ERROR_TABLE;
|
||||
et return ERROR_TABLE;
|
||||
error_code return ERROR_CODE_ENTRY;
|
||||
ec return ERROR_CODE_ENTRY;
|
||||
end return END;
|
||||
|
||||
[\t ]+ ;
|
||||
\n ++yylineno;
|
||||
|
||||
\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1);
|
||||
if (p=rindex(yylval.dynstr, '"')) *p='\0';
|
||||
return QUOTED_STRING;
|
||||
}
|
||||
|
||||
{AN}* { yylval.dynstr = ds(yytext); return STRING; }
|
||||
|
||||
#.*\n ++yylineno;
|
||||
|
||||
. { return (*yytext); }
|
||||
%%
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987 by MIT Student Information Processing Board
|
||||
* For copyright info, see Copyright.SIPB.
|
||||
*
|
||||
* $Id: et_name.c,v 1.2 1994/07/19 19:21:27 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#include "error_table.h"
|
||||
|
||||
static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
|
||||
|
||||
char *malloc();
|
||||
|
||||
char *
|
||||
error_table_name(num)
|
||||
int num;
|
||||
{
|
||||
register int ch;
|
||||
register int i;
|
||||
register char *buf, *p;
|
||||
|
||||
/* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
|
||||
buf = malloc(5);
|
||||
p = buf;
|
||||
num >>= ERRCODE_RANGE;
|
||||
/* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
|
||||
num &= 077777777;
|
||||
/* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
|
||||
for (i = 0; i < 5; i++) {
|
||||
ch = (num >> 24-6*i) & 077;
|
||||
if (ch == 0)
|
||||
continue;
|
||||
else if (ch < 27)
|
||||
*p++ = ch - 1 + 'A';
|
||||
else if (ch < 53)
|
||||
*p++ = ch - 27 + 'a';
|
||||
else if (ch < 63)
|
||||
*p++ = ch - 53 + '0';
|
||||
else /* ch == 63 */
|
||||
*p++ = '_';
|
||||
}
|
||||
return(buf);
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986 by MIT Information Systems and
|
||||
* MIT Student Information Processing Board
|
||||
* For copyright info, see Copyright.SIPB.
|
||||
*
|
||||
* form: init_et.c,v 1.1 86/11/10 21:42:26 spook Exp $
|
||||
* $Id: init_et.c,v 1.2 1994/07/19 19:21:28 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "error_table.h"
|
||||
|
||||
static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
|
||||
|
||||
extern char *malloc(), *realloc();
|
||||
|
||||
/* useful */
|
||||
typedef error_table *etp;
|
||||
typedef etp *etpp;
|
||||
|
||||
etpp _et_list = (etpp)NULL;
|
||||
static int n_allocated = 0, n_used = 0;
|
||||
|
||||
int
|
||||
init_error_table(msgs, base, count)
|
||||
char **msgs;
|
||||
register int base;
|
||||
int count;
|
||||
{
|
||||
register int i;
|
||||
register etp new_et;
|
||||
register etpp list;
|
||||
|
||||
if (!base || !count || !msgs)
|
||||
return;
|
||||
|
||||
new_et = (etp)malloc(sizeof(error_table));
|
||||
new_et->msgs = msgs;
|
||||
new_et->base = base;
|
||||
new_et->n_msgs= count;
|
||||
|
||||
list = _et_list;
|
||||
if (list == (etpp)NULL) {
|
||||
_et_list = (etpp) malloc(10*sizeof(etp));
|
||||
list = _et_list;
|
||||
if (list == (etpp)NULL)
|
||||
return; /* oops */
|
||||
list[0] = new_et;
|
||||
list[1] = (etp)NULL;
|
||||
n_allocated = 10;
|
||||
n_used = 1;
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < n_used; i++)
|
||||
if (list[i]->base == base)
|
||||
return; /* avoid duplicates */
|
||||
if (n_used+2 > n_allocated) {
|
||||
n_allocated += 10; /* don't re-allocate too often */
|
||||
list = (etpp) realloc((char *)list,
|
||||
(unsigned)n_allocated * sizeof(etp));
|
||||
_et_list = list;
|
||||
if (list == (etpp)NULL)
|
||||
return; /* oops */
|
||||
}
|
||||
list[n_used++] = new_et;
|
||||
list[n_used] = (etp)NULL;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987 by MIT Student Information Processing Board
|
||||
* For copyright info, see Copyright.SIPB
|
||||
*
|
||||
* $Id: perror.c,v 1.2 1994/07/19 19:21:30 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include "error_table.h"
|
||||
|
||||
typedef int (*int_func)();
|
||||
|
||||
#if defined(mips) && defined(ultrix)
|
||||
int errno; /* this is needed to keep the loader from complaining */
|
||||
#endif
|
||||
|
||||
int_func com_err_hook = (int_func) NULL;
|
||||
char *error_message();
|
||||
|
||||
void
|
||||
com_err(whoami, code, message)
|
||||
char *whoami;
|
||||
int code;
|
||||
char *message;
|
||||
{
|
||||
struct iovec strings[6];
|
||||
|
||||
if (com_err_hook) {
|
||||
(*com_err_hook)(whoami, code, message);
|
||||
return;
|
||||
}
|
||||
|
||||
strings[0].iov_base = whoami;
|
||||
strings[0].iov_len = strlen(whoami);
|
||||
if (whoami) {
|
||||
strings[1].iov_base = ": ";
|
||||
strings[1].iov_len = 2;
|
||||
} else
|
||||
strings[1].iov_len = 0;
|
||||
if (code) {
|
||||
register char *errmsg = error_message(code);
|
||||
strings[2].iov_base = errmsg;
|
||||
strings[2].iov_len = strlen(errmsg);
|
||||
} else
|
||||
strings[2].iov_len = 0;
|
||||
strings[3].iov_base = " ";
|
||||
strings[3].iov_len = 1;
|
||||
strings[4].iov_base = message;
|
||||
strings[4].iov_len = strlen(message);
|
||||
strings[5].iov_base = "\n";
|
||||
strings[5].iov_len = 1;
|
||||
(void) writev(2, strings, 6);
|
||||
}
|
||||
|
||||
int_func
|
||||
set_com_err_hook(new_proc)
|
||||
int_func new_proc;
|
||||
{
|
||||
register int_func x = com_err_hook;
|
||||
com_err_hook = new_proc;
|
||||
return (x);
|
||||
}
|
||||
|
||||
reset_com_err_hook()
|
||||
{
|
||||
com_err_hook = (int_func) NULL;
|
||||
}
|
||||
|
||||
void
|
||||
perror(msg)
|
||||
register const char *msg;
|
||||
{
|
||||
com_err(msg, errno, (char *)NULL);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "test1.h"
|
||||
#include "test2.h"
|
||||
char *error_message();
|
||||
extern int sys_nerr, errno;
|
||||
|
||||
main()
|
||||
{
|
||||
printf("\nBefore initiating error table:\n\n");
|
||||
printf("Table name '%s'\n", error_table_name(KRB_MK_AP_TGTEXP));
|
||||
printf("UNIX name '%s'\n", error_table_name(EPERM));
|
||||
printf("Msg TGT-expired is '%s'\n", error_message(KRB_MK_AP_TGTEXP));
|
||||
printf("Msg EPERM is '%s'\n", error_message(EPERM));
|
||||
printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR));
|
||||
printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1));
|
||||
printf("Msg {sys_nerr} is '%s'\n", error_message(sys_nerr));
|
||||
|
||||
init_error_table(0, 0, 0);
|
||||
printf("With 0: tgt-expired -> %s\n", error_message(KRB_MK_AP_TGTEXP));
|
||||
|
||||
init_krb_err_tbl();
|
||||
printf("KRB error table initialized: base %d (%s), name %s\n",
|
||||
krb_err_base, error_message(krb_err_base),
|
||||
error_table_name(krb_err_base));
|
||||
printf("With krb: tgt-expired -> %s\n",
|
||||
error_message(KRB_MK_AP_TGTEXP));
|
||||
|
||||
init_quux_err_tbl();
|
||||
printf("QUUX error table initialized: base %d (%s), name %s\n",
|
||||
quux_err_base, error_message(quux_err_base),
|
||||
error_table_name(quux_err_base));
|
||||
|
||||
printf("Msg for TGT-expired is '%s'\n",
|
||||
error_message(KRB_MK_AP_TGTEXP));
|
||||
printf("Msg {sys_nerr-1} is '%s'\n", error_message(sys_nerr-1));
|
||||
printf("Msg FOO_ERR is '%s'\n", error_message(FOO_ERR));
|
||||
printf("Msg KRB_SKDC_CANT is '%s'\n",
|
||||
error_message(KRB_SKDC_CANT));
|
||||
printf("Msg 1e6 is '%s'\n", error_message(1000000));
|
||||
errno = FOO_ERR;
|
||||
perror("FOO_ERR");
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
error_table krb
|
||||
|
||||
error_code KRB_MK_AP_TKFIL,
|
||||
"Can't read ticket file"
|
||||
|
||||
ec KRB_MK_AP_NOTKT,
|
||||
"Can't find ticket or TGT"
|
||||
|
||||
ec KRB_MK_AP_TGTEXP,
|
||||
"TGT expired"
|
||||
|
||||
ec KRB_RD_AP_UNDEC,
|
||||
"Can't decode authenticator"
|
||||
|
||||
ec KRB_RD_AP_EXP,
|
||||
"Ticket expired"
|
||||
|
||||
ec KRB_RD_AP_REPEAT,
|
||||
"Repeated request"
|
||||
|
||||
ec KRB_RD_AP_NOT_US,
|
||||
"The ticket isn't for us"
|
||||
|
||||
ec KRB_RD_AP_INCON,
|
||||
"Request is inconsistent"
|
||||
|
||||
ec KRB_RD_AP_TIME,
|
||||
"Delta-T too big"
|
||||
|
||||
ec KRB_RD_AP_BADD,
|
||||
"Incorrect net address"
|
||||
|
||||
ec KRB_RD_AP_VERSION,
|
||||
"Protocol version mismatch"
|
||||
|
||||
ec KRB_RD_AP_MSG_TYPE,
|
||||
"Invalid message type"
|
||||
|
||||
ec KRB_RD_AP_MODIFIED,
|
||||
"Message stream modified"
|
||||
|
||||
ec KRB_RD_AP_ORDER,
|
||||
"Message out of order"
|
||||
|
||||
ec KRB_RD_AP_UNAUTHOR,
|
||||
"Unauthorized request"
|
||||
|
||||
ec KRB_GT_PW_NULL,
|
||||
"Current password is null"
|
||||
|
||||
ec KRB_GT_PW_BADPW,
|
||||
"Incorrect current password"
|
||||
|
||||
ec KRB_GT_PW_PROT,
|
||||
"Protocol error"
|
||||
|
||||
ec KRB_GT_PW_KDCERR,
|
||||
"Error returned by KDC"
|
||||
|
||||
ec KRB_GT_PW_NULLTKT,
|
||||
"Null ticket returned by KDC"
|
||||
|
||||
ec KRB_SKDC_RETRY,
|
||||
"Retry count exceeded"
|
||||
|
||||
ec KRB_SKDC_CANT,
|
||||
"Can't send request"
|
||||
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
error_table quux
|
||||
|
||||
ec FOO_ERR, "foo"
|
||||
|
||||
ec BAR_ERR, "bar"
|
||||
|
||||
ec BAZ_ERR, "meow"
|
||||
|
||||
end
|
||||
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* $Source: /usr/src/kerberosIV/des/RCS/new_rnd_key.c,v $
|
||||
* $Author: bostic $
|
||||
*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <mit-copyright.h>.
|
||||
*
|
||||
* New pseudo-random key generator, using DES encryption to make the
|
||||
* pseudo-random cycle as hard to break as DES.
|
||||
*
|
||||
* Written by Mark Lillibridge, MIT Project Athena
|
||||
*
|
||||
* Under U.S. law, this software may not be exported outside the US
|
||||
* without license from the U.S. Commerce department.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid_new_rnd_key_c[] =
|
||||
"$Header: /usr/src/kerberosIV/des/RCS/new_rnd_key.c,v 4.2 91/02/25 15:14:22 bostic Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <mit-copyright.h>
|
||||
|
||||
#include <des.h>
|
||||
#include "des_internal.h"
|
||||
|
||||
extern void des_fixup_key_parity();
|
||||
extern int des_is_weak_key();
|
||||
|
||||
void des_set_random_generator_seed(), des_set_sequence_number();
|
||||
void des_generate_random_block();
|
||||
|
||||
/*
|
||||
* des_new_random_key: create a random des key
|
||||
*
|
||||
* Requires: des_set_random_number_generater_seed must be at called least
|
||||
* once before this routine is called.
|
||||
*
|
||||
* Notes: the returned key has correct parity and is guarenteed not
|
||||
* to be a weak des key. Des_generate_random_block is used to
|
||||
* provide the random bits.
|
||||
*/
|
||||
int
|
||||
des_new_random_key(key)
|
||||
des_cblock key;
|
||||
{
|
||||
do {
|
||||
des_generate_random_block(key);
|
||||
des_fixup_key_parity(key);
|
||||
} while (des_is_weak_key(key));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* des_init_random_number_generator:
|
||||
*
|
||||
* This routine takes a secret key possibly shared by a number
|
||||
* of servers and uses it to generate a random number stream that is
|
||||
* not shared by any of the other servers. It does this by using the current
|
||||
* process id, host id, and the current time to the nearest second. The
|
||||
* resulting stream seed is not useful information for cracking the secret
|
||||
* key. Moreover, this routine keeps no copy of the secret key.
|
||||
* This routine is used for example, by the kerberos server(s) with the
|
||||
* key in question being the kerberos master key.
|
||||
*
|
||||
* Note: this routine calls des_set_random_generator_seed.
|
||||
*/
|
||||
#ifndef BSDUNIX
|
||||
you lose... (aka, you get to implement an analog of this for your
|
||||
system...)
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
void des_init_random_number_generator(key)
|
||||
des_cblock key;
|
||||
{
|
||||
struct { /* This must be 64 bits exactly */
|
||||
long process_id;
|
||||
long host_id;
|
||||
} seed;
|
||||
struct timeval time; /* this must also be 64 bits exactly */
|
||||
des_cblock new_key;
|
||||
long gethostid();
|
||||
|
||||
/*
|
||||
* use a host id and process id in generating the seed to ensure
|
||||
* that different servers have different streams:
|
||||
*/
|
||||
seed.host_id = gethostid();
|
||||
seed.process_id = getpid();
|
||||
|
||||
/*
|
||||
* Generate a tempory value that depends on the key, host_id, and
|
||||
* process_id such that it gives no useful information about the key:
|
||||
*/
|
||||
des_set_random_generator_seed(key);
|
||||
des_set_sequence_number((unsigned char *)&seed);
|
||||
des_new_random_key(new_key);
|
||||
|
||||
/*
|
||||
* use it to select a random stream:
|
||||
*/
|
||||
des_set_random_generator_seed(new_key);
|
||||
|
||||
/*
|
||||
* use a time stamp to ensure that a server started later does not reuse
|
||||
* an old stream:
|
||||
*/
|
||||
gettimeofday(&time, (struct timezone *)0);
|
||||
des_set_sequence_number((unsigned char *)&time);
|
||||
|
||||
/*
|
||||
* use the time stamp finally to select the final seed using the
|
||||
* current random number stream:
|
||||
*/
|
||||
des_new_random_key(new_key);
|
||||
des_set_random_generator_seed(new_key);
|
||||
}
|
||||
|
||||
#endif /* ifdef BSDUNIX */
|
||||
|
||||
/*
|
||||
* This module implements a random number generator faculty such that the next
|
||||
* number in any random number stream is very hard to predict without knowing
|
||||
* the seed for that stream even given the preceeding random numbers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The secret des key schedule for the current stream of random numbers:
|
||||
*/
|
||||
static des_key_schedule random_sequence_key;
|
||||
|
||||
/*
|
||||
* The sequence # in the current stream of random numbers:
|
||||
*/
|
||||
static unsigned char sequence_number[8];
|
||||
|
||||
/*
|
||||
* des_set_random_generator_seed: this routine is used to select a random
|
||||
* number stream. The stream that results is
|
||||
* totally determined by the passed in key.
|
||||
* (I.e., calling this routine again with the
|
||||
* same key allows repeating a sequence of
|
||||
* random numbers)
|
||||
*
|
||||
* Requires: key is a valid des key. I.e., has correct parity and is not a
|
||||
* weak des key.
|
||||
*/
|
||||
void
|
||||
des_set_random_generator_seed(key)
|
||||
des_cblock key;
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* select the new stream: (note errors are not possible here...) */
|
||||
des_key_sched(key, random_sequence_key);
|
||||
|
||||
/* "seek" to the start of the stream: */
|
||||
for (i=0; i<8; i++)
|
||||
sequence_number[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* des_set_sequence_number: this routine is used to set the sequence number
|
||||
* of the current random number stream. This routine
|
||||
* may be used to "seek" within the current random
|
||||
* number stream.
|
||||
*
|
||||
* Note that des_set_random_generator_seed resets the sequence number to 0.
|
||||
*/
|
||||
void
|
||||
des_set_sequence_number(new_sequence_number)
|
||||
des_cblock new_sequence_number;
|
||||
{
|
||||
bcopy((char *)new_sequence_number, (char *)sequence_number,
|
||||
sizeof(sequence_number));
|
||||
}
|
||||
|
||||
/*
|
||||
* des_generate_random_block: routine to return the next random number
|
||||
* from the current random number stream.
|
||||
* The returned number is 64 bits long.
|
||||
*
|
||||
* Requires: des_set_random_generator_seed must have been called at least once
|
||||
* before this routine is called.
|
||||
*/
|
||||
void des_generate_random_block(block)
|
||||
des_cblock block;
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Encrypt the sequence number to get the new random block:
|
||||
*/
|
||||
des_ecb_encrypt(sequence_number, block, random_sequence_key, 1);
|
||||
|
||||
/*
|
||||
* Increment the sequence number as an 8 byte unsigned number with wrap:
|
||||
* (using LSB here)
|
||||
*/
|
||||
for (i=0; i<8; i++) {
|
||||
sequence_number[i] = (sequence_number[i] + 1) & 0xff;
|
||||
if (sequence_number[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* Definitions for Kerberos administration server & client
|
||||
*
|
||||
* from: kadm.h,v 4.2 89/09/26 09:15:20 jtkohl Exp $
|
||||
* $Id: kadm.h,v 1.2 1994/07/19 19:23:09 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef KADM_DEFS
|
||||
#define KADM_DEFS
|
||||
|
||||
/*
|
||||
* kadm.h
|
||||
* Header file for the fourth attempt at an admin server
|
||||
* Doug Church, December 28, 1989, MIT Project Athena
|
||||
*/
|
||||
|
||||
/* for those broken Unixes without this defined... should be in sys/param.h */
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <krb.h>
|
||||
#include <des.h>
|
||||
|
||||
/* The global structures for the client and server */
|
||||
typedef struct {
|
||||
struct sockaddr_in admin_addr;
|
||||
struct sockaddr_in my_addr;
|
||||
int my_addr_len;
|
||||
int admin_fd; /* file descriptor for link to admin server */
|
||||
char sname[ANAME_SZ]; /* the service name */
|
||||
char sinst[INST_SZ]; /* the services instance */
|
||||
char krbrlm[REALM_SZ];
|
||||
} Kadm_Client;
|
||||
|
||||
typedef struct { /* status of the server, i.e the parameters */
|
||||
int inter; /* Space for command line flags */
|
||||
char *sysfile; /* filename of server */
|
||||
} admin_params; /* Well... it's the admin's parameters */
|
||||
|
||||
/* Largest password length to be supported */
|
||||
#define MAX_KPW_LEN 128
|
||||
|
||||
/* Largest packet the admin server will ever allow itself to return */
|
||||
#define KADM_RET_MAX 2048
|
||||
|
||||
/* That's right, versions are 8 byte strings */
|
||||
#define KADM_VERSTR "KADM0.0A"
|
||||
#define KADM_ULOSE "KYOULOSE" /* sent back when server can't
|
||||
decrypt client's msg */
|
||||
#define KADM_VERSIZE strlen(KADM_VERSTR)
|
||||
|
||||
/* the lookups for the server instances */
|
||||
#define PWSERV_NAME "changepw"
|
||||
#define KADM_SNAME "kerberos_master"
|
||||
#define KADM_SINST "kerberos"
|
||||
|
||||
/* Attributes fields constants and macros */
|
||||
#define ALLOC 2
|
||||
#define RESERVED 3
|
||||
#define DEALLOC 4
|
||||
#define DEACTIVATED 5
|
||||
#define ACTIVE 6
|
||||
|
||||
/* Kadm_vals structure for passing db fields into the server routines */
|
||||
#define FLDSZ 4
|
||||
|
||||
typedef struct {
|
||||
u_char fields[FLDSZ]; /* The active fields in this struct */
|
||||
char name[ANAME_SZ];
|
||||
char instance[INST_SZ];
|
||||
unsigned long key_low;
|
||||
unsigned long key_high;
|
||||
unsigned long exp_date;
|
||||
unsigned short attributes;
|
||||
unsigned char max_life;
|
||||
} Kadm_vals; /* The basic values structure in Kadm */
|
||||
|
||||
/* Kadm_vals structure for passing db fields into the server routines */
|
||||
#define FLDSZ 4
|
||||
|
||||
/* Need to define fields types here */
|
||||
#define KADM_NAME 31
|
||||
#define KADM_INST 30
|
||||
#define KADM_EXPDATE 29
|
||||
#define KADM_ATTR 28
|
||||
#define KADM_MAXLIFE 27
|
||||
#define KADM_DESKEY 26
|
||||
|
||||
/* To set a field entry f in a fields structure d */
|
||||
#define SET_FIELD(f,d) (d[3-(f/8)]|=(1<<(f%8)))
|
||||
|
||||
/* To set a field entry f in a fields structure d */
|
||||
#define CLEAR_FIELD(f,d) (d[3-(f/8)]&=(~(1<<(f%8))))
|
||||
|
||||
/* Is field f in fields structure d */
|
||||
#define IS_FIELD(f,d) (d[3-(f/8)]&(1<<(f%8)))
|
||||
|
||||
/* Various return codes */
|
||||
#define KADM_SUCCESS 0
|
||||
|
||||
#define WILDCARD_STR "*"
|
||||
|
||||
enum acl_types {
|
||||
ADDACL,
|
||||
GETACL,
|
||||
MODACL
|
||||
};
|
||||
|
||||
/* Various opcodes for the admin server's functions */
|
||||
#define CHANGE_PW 2
|
||||
#define ADD_ENT 3
|
||||
#define MOD_ENT 4
|
||||
#define GET_ENT 5
|
||||
|
||||
extern long kdb_get_master_key(); /* XXX should be in krb_db.h */
|
||||
extern long kdb_verify_master_key(); /* XXX ditto */
|
||||
|
||||
extern long krb_mk_priv(), krb_rd_priv(); /* XXX should be in krb.h */
|
||||
extern void krb_set_tkt_string(); /* XXX ditto */
|
||||
|
||||
extern unsigned long quad_cksum(); /* XXX should be in des.h */
|
||||
|
||||
/* XXX This doesn't belong here!!! */
|
||||
char *malloc(), *realloc();
|
||||
#ifdef POSIX
|
||||
typedef void sigtype;
|
||||
#else
|
||||
typedef int sigtype;
|
||||
#endif
|
||||
|
||||
#endif KADM_DEFS
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 1989 by the Massachusetts Institute of Technology
|
||||
|
||||
Export of this software from the United States of America is assumed
|
||||
to require a specific license from the United States Government.
|
||||
It is the responsibility of any person or organization contemplating
|
||||
export to obtain such a license before exporting.
|
||||
|
||||
WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
distribute this software and its documentation for any purpose and
|
||||
without fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright notice and
|
||||
this permission notice appear in supporting documentation, and that
|
||||
the name of M.I.T. not be used in advertising or publicity pertaining
|
||||
to distribution of the software without specific, written prior
|
||||
permission. M.I.T. makes no representations about the suitability of
|
||||
this software for any purpose. It is provided "as is" without express
|
||||
or implied warranty.
|
||||
|
||||
*/
|
||||
@@ -1,10 +0,0 @@
|
||||
# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
|
||||
# $Id: Makefile,v 1.3 1994/09/09 21:43:17 g89r4222 Exp $
|
||||
|
||||
LIB= acl
|
||||
SHLIB_MAJOR= 2
|
||||
SHLIB_MINOR= 0
|
||||
CFLAGS+=-DDEBUG -DKERBEROS -I${.CURDIR}/../include
|
||||
SRCS= acl_files.c
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,183 +0,0 @@
|
||||
.\" from: acl_check.3,v 4.1 89/01/23 11:06:54 jtkohl Exp $
|
||||
.\" $Id: acl_check.3,v 1.1.1.1 1994/09/30 14:50:05 csgr Exp $
|
||||
.\" Copyright 1989 by the Massachusetts Institute of Technology.
|
||||
.\"
|
||||
.\" For copying and distribution information,
|
||||
.\" please see the file <Copyright.MIT>.
|
||||
.\"
|
||||
.TH ACL_CHECK 3 "Kerberos Version 4.0" "MIT Project Athena"
|
||||
.SH NAME
|
||||
acl_canonicalize_principal, acl_check, acl_exact_match, acl_add,
|
||||
acl_delete, acl_initialize \- Access control list routines
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.nj
|
||||
.ft B
|
||||
cc <files> \-lacl \-lkrb
|
||||
.PP
|
||||
.ft B
|
||||
#include <kerberosIV/krb.h>
|
||||
.PP
|
||||
.ft B
|
||||
acl_canonicalize_principal(principal, buf)
|
||||
char *principal;
|
||||
char *buf;
|
||||
.PP
|
||||
.ft B
|
||||
acl_check(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
.PP
|
||||
.ft B
|
||||
acl_exact_match(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
.PP
|
||||
.ft B
|
||||
acl_add(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
.PP
|
||||
.ft B
|
||||
acl_delete(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
.PP
|
||||
.ft B
|
||||
acl_initialize(acl_file, mode)
|
||||
char *acl_file;
|
||||
int mode;
|
||||
.fi
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
.SS Introduction
|
||||
.PP
|
||||
An access control list (ACL) is a list of principals, where each
|
||||
principal is represented by a text string which cannot contain
|
||||
whitespace. The library allows application programs to refer to named
|
||||
access control lists to test membership and to atomically add and
|
||||
delete principals using a natural and intuitive interface. At
|
||||
present, the names of access control lists are required to be Unix
|
||||
filenames, and refer to human-readable Unix files; in the future, when
|
||||
a networked ACL server is implemented, the names may refer to a
|
||||
different namespace specific to the ACL service.
|
||||
.PP
|
||||
.SS Principal Names
|
||||
.PP
|
||||
Principal names have the form
|
||||
.nf
|
||||
.in +5n
|
||||
<name>[.<instance>][@<realm>]
|
||||
.in -5n
|
||||
e.g.:
|
||||
.in +5n
|
||||
asp
|
||||
asp.root
|
||||
[email protected]
|
||||
[email protected]
|
||||
[email protected]
|
||||
.in -5n
|
||||
.fi
|
||||
It is possible for principals to be underspecified. If an instance is
|
||||
missing, it is assumed to be "". If realm is missing, it is assumed
|
||||
to be the local realm as determined by
|
||||
.IR krb_get_lrealm (3).
|
||||
The canonical form contains all of name, instance,
|
||||
and realm; the acl_add and acl_delete routines will always
|
||||
leave the file in that form. Note that the canonical form of
|
||||
[email protected] is actually [email protected].
|
||||
.SS Routines
|
||||
.PP
|
||||
.I acl_canonicalize_principal
|
||||
stores the canonical form of
|
||||
.I principal
|
||||
in
|
||||
.IR buf .
|
||||
.I Buf
|
||||
must contain enough
|
||||
space to store a principal, given the limits on the sizes of name,
|
||||
instance, and realm specified as ANAME_SZ, INST_SZ, and REALM_SZ,
|
||||
respectively, in
|
||||
.IR /usr/include/kerberosIV/krb.h .
|
||||
.PP
|
||||
.I acl_check
|
||||
returns nonzero if
|
||||
.I principal
|
||||
appears in
|
||||
.IR acl .
|
||||
Returns 0 if principal
|
||||
does not appear in acl, or if an error occurs. Canonicalizes
|
||||
principal before checking, and allows the ACL to contain wildcards. The
|
||||
only supported wildcards are entries of the form
|
||||
name.*@realm, *.*@realm, and *.*@*. An asterisk matches any value for the
|
||||
its component field. For example, "jtkohl.*@*" would match principal
|
||||
jtkohl, with any instance and any realm.
|
||||
.PP
|
||||
.I acl_exact_match
|
||||
performs like
|
||||
.IR acl_check ,
|
||||
but does no canonicalization or wildcard matching.
|
||||
.PP
|
||||
.I acl_add
|
||||
atomically adds
|
||||
.I principal
|
||||
to
|
||||
.IR acl .
|
||||
Returns 0 if successful, nonzero otherwise. It is considered a failure
|
||||
if
|
||||
.I principal
|
||||
is already in
|
||||
.IR acl .
|
||||
This routine will canonicalize
|
||||
.IR principal ,
|
||||
but will treat wildcards literally.
|
||||
.PP
|
||||
.I acl_delete
|
||||
atomically deletes
|
||||
.I principal
|
||||
from
|
||||
.IR acl .
|
||||
Returns 0 if successful,
|
||||
nonzero otherwise. It is considered a failure if
|
||||
.I principal
|
||||
is not
|
||||
already in
|
||||
.IR acl .
|
||||
This routine will canonicalize
|
||||
.IR principal ,
|
||||
but will treat wildcards literally.
|
||||
.PP
|
||||
.I acl_initialize
|
||||
initializes
|
||||
.IR acl_file .
|
||||
If the file
|
||||
.I acl_file
|
||||
does not exist,
|
||||
.I acl_initialize
|
||||
creates it with mode
|
||||
.IR mode .
|
||||
If the file
|
||||
.I acl_file
|
||||
exists,
|
||||
.I acl_initialize
|
||||
removes all members. Returns 0 if successful,
|
||||
nonzero otherwise. WARNING: Mode argument is likely to change with
|
||||
the eventual introduction of an ACL service.
|
||||
.SH NOTES
|
||||
In the presence of concurrency, there is a very small chance that
|
||||
.I acl_add
|
||||
or
|
||||
.I acl_delete
|
||||
could report success even though it would have
|
||||
had no effect. This is a necessary side effect of using lock files
|
||||
for concurrency control rather than flock(2), which is not supported
|
||||
by NFS.
|
||||
.PP
|
||||
The current implementation caches ACLs in memory in a hash-table
|
||||
format for increased efficiency in checking membership; one effect of
|
||||
the caching scheme is that one file descriptor will be kept open for
|
||||
each ACL cached, up to a maximum of 8.
|
||||
.SH SEE ALSO
|
||||
kerberos(3), krb_get_lrealm(3)
|
||||
.SH AUTHOR
|
||||
James Aspnes (MIT Project Athena)
|
||||
@@ -1,541 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 1987,1989 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <mit-copyright.h>.
|
||||
*
|
||||
* from: acl_files.c,v 4.4 89/12/19 13:30:53 jtkohl Exp $
|
||||
* $Id: acl_files.c,v 1.1.1.1 1994/09/30 14:49:48 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: acl_files.c,v 1.1.1.1 1994/09/30 14:49:48 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
|
||||
/*** Routines for manipulating access control list files ***/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
#include <ctype.h>
|
||||
#include "krb.h"
|
||||
|
||||
__BEGIN_DECLS
|
||||
static int acl_abort __P((char *, FILE *));
|
||||
__END_DECLS
|
||||
|
||||
#ifndef KRB_REALM
|
||||
#define KRB_REALM "ATHENA.MIT.EDU"
|
||||
#endif
|
||||
|
||||
/* "aname.inst@realm" */
|
||||
#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3)
|
||||
#define INST_SEP '.'
|
||||
#define REALM_SEP '@'
|
||||
|
||||
#define LINESIZE 2048 /* Maximum line length in an acl file */
|
||||
|
||||
#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */
|
||||
#define WAIT_TIME 300 /* Maximum time allowed write acl file */
|
||||
|
||||
#define CACHED_ACLS 8 /* How many acls to cache */
|
||||
/* Each acl costs 1 open file descriptor */
|
||||
#define ACL_LEN 16 /* Twice a reasonable acl length */
|
||||
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
#define COR(a,b) ((a!=NULL)?(a):(b))
|
||||
|
||||
extern int errno;
|
||||
|
||||
extern char *malloc(), *calloc();
|
||||
extern time_t time();
|
||||
|
||||
/* Canonicalize a principal name */
|
||||
/* If instance is missing, it becomes "" */
|
||||
/* If realm is missing, it becomes the local realm */
|
||||
/* Canonicalized form is put in canon, which must be big enough to hold
|
||||
MAX_PRINCIPAL_SIZE characters */
|
||||
acl_canonicalize_principal(principal, canon)
|
||||
char *principal;
|
||||
char *canon;
|
||||
{
|
||||
char *dot, *atsign, *end;
|
||||
int len;
|
||||
|
||||
dot = index(principal, INST_SEP);
|
||||
atsign = index(principal, REALM_SEP);
|
||||
|
||||
/* Maybe we're done already */
|
||||
if(dot != NULL && atsign != NULL) {
|
||||
if(dot < atsign) {
|
||||
/* It's for real */
|
||||
/* Copy into canon */
|
||||
strncpy(canon, principal, MAX_PRINCIPAL_SIZE);
|
||||
canon[MAX_PRINCIPAL_SIZE-1] = '\0';
|
||||
return;
|
||||
} else {
|
||||
/* Nope, it's part of the realm */
|
||||
dot = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* No such luck */
|
||||
end = principal + strlen(principal);
|
||||
|
||||
/* Get the principal name */
|
||||
len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal);
|
||||
strncpy(canon, principal, len);
|
||||
canon += len;
|
||||
|
||||
/* Add INST_SEP */
|
||||
*canon++ = INST_SEP;
|
||||
|
||||
/* Get the instance, if it exists */
|
||||
if(dot != NULL) {
|
||||
++dot;
|
||||
len = MIN(INST_SZ, COR(atsign, end) - dot);
|
||||
strncpy(canon, dot, len);
|
||||
canon += len;
|
||||
}
|
||||
|
||||
/* Add REALM_SEP */
|
||||
*canon++ = REALM_SEP;
|
||||
|
||||
/* Get the realm, if it exists */
|
||||
/* Otherwise, default to local realm */
|
||||
if(atsign != NULL) {
|
||||
++atsign;
|
||||
len = MIN(REALM_SZ, end - atsign);
|
||||
strncpy(canon, atsign, len);
|
||||
canon += len;
|
||||
*canon++ = '\0';
|
||||
} else if(krb_get_lrealm(canon, 1) != KSUCCESS) {
|
||||
strcpy(canon, KRB_REALM);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a lock to modify acl_file */
|
||||
/* Return new FILE pointer */
|
||||
/* or NULL if file cannot be modified */
|
||||
/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */
|
||||
static FILE *acl_lock_file(acl_file)
|
||||
char *acl_file;
|
||||
{
|
||||
struct stat s;
|
||||
char new[LINESIZE];
|
||||
int nfd;
|
||||
FILE *nf;
|
||||
int mode;
|
||||
|
||||
if(stat(acl_file, &s) < 0) return(NULL);
|
||||
mode = s.st_mode;
|
||||
sprintf(new, NEW_FILE, acl_file);
|
||||
for(;;) {
|
||||
/* Open the new file */
|
||||
if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) {
|
||||
if(errno == EEXIST) {
|
||||
/* Maybe somebody got here already, maybe it's just old */
|
||||
if(stat(new, &s) < 0) return(NULL);
|
||||
if(time(0) - s.st_ctime > WAIT_TIME) {
|
||||
/* File is stale, kill it */
|
||||
unlink(new);
|
||||
continue;
|
||||
} else {
|
||||
/* Wait and try again */
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* Some other error, we lose */
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got to here, the lock file is ours and ok */
|
||||
/* Reopen it under stdio */
|
||||
if((nf = fdopen(nfd, "w")) == NULL) {
|
||||
/* Oops, clean up */
|
||||
unlink(new);
|
||||
}
|
||||
return(nf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit changes to acl_file written onto FILE *f */
|
||||
/* Returns zero if successful */
|
||||
/* Returns > 0 if lock was broken */
|
||||
/* Returns < 0 if some other error occurs */
|
||||
/* Closes f */
|
||||
static int acl_commit(acl_file, f)
|
||||
char *acl_file;
|
||||
FILE *f;
|
||||
{
|
||||
char new[LINESIZE];
|
||||
int ret;
|
||||
struct stat s;
|
||||
|
||||
sprintf(new, NEW_FILE, acl_file);
|
||||
if(fflush(f) < 0
|
||||
|| fstat(fileno(f), &s) < 0
|
||||
|| s.st_nlink == 0) {
|
||||
acl_abort(acl_file, f);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ret = rename(new, acl_file);
|
||||
fclose(f);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Abort changes to acl_file written onto FILE *f
|
||||
* Returns 0 if successful, < 0 otherwise
|
||||
* Closes f
|
||||
*/
|
||||
static int
|
||||
acl_abort(acl_file, f)
|
||||
char *acl_file;
|
||||
FILE *f;
|
||||
{
|
||||
char new[LINESIZE];
|
||||
int ret;
|
||||
struct stat s;
|
||||
|
||||
/* make sure we aren't nuking someone else's file */
|
||||
if(fstat(fileno(f), &s) < 0 || s.st_nlink == 0) {
|
||||
fclose(f);
|
||||
return(-1);
|
||||
} else {
|
||||
sprintf(new, NEW_FILE, acl_file);
|
||||
ret = unlink(new);
|
||||
fclose(f);
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize an acl_file */
|
||||
/* Creates the file with permissions perm if it does not exist */
|
||||
/* Erases it if it does */
|
||||
/* Returns return value of acl_commit */
|
||||
int acl_initialize(acl_file, perm)
|
||||
char *acl_file;
|
||||
int perm;
|
||||
{
|
||||
FILE *new;
|
||||
int fd;
|
||||
|
||||
/* Check if the file exists already */
|
||||
if((new = acl_lock_file(acl_file)) != NULL) {
|
||||
return(acl_commit(acl_file, new));
|
||||
} else {
|
||||
/* File must be readable and writable by owner */
|
||||
if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) {
|
||||
return(-1);
|
||||
} else {
|
||||
close(fd);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Eliminate all whitespace character in buf */
|
||||
/* Modifies its argument */
|
||||
static nuke_whitespace(buf)
|
||||
char *buf;
|
||||
{
|
||||
register char *pin, *pout;
|
||||
|
||||
for(pin = pout = buf; *pin != '\0'; pin++)
|
||||
if(!isspace(*pin)) *pout++ = *pin;
|
||||
*pout = '\0'; /* Terminate the string */
|
||||
}
|
||||
|
||||
/* Hash table stuff */
|
||||
|
||||
struct hashtbl {
|
||||
int size; /* Max number of entries */
|
||||
int entries; /* Actual number of entries */
|
||||
char **tbl; /* Pointer to start of table */
|
||||
};
|
||||
|
||||
/* Make an empty hash table of size s */
|
||||
static struct hashtbl *make_hash(size)
|
||||
int size;
|
||||
{
|
||||
struct hashtbl *h;
|
||||
|
||||
if(size < 1) size = 1;
|
||||
h = (struct hashtbl *) malloc(sizeof(struct hashtbl));
|
||||
h->size = size;
|
||||
h->entries = 0;
|
||||
h->tbl = (char **) calloc(size, sizeof(char *));
|
||||
return(h);
|
||||
}
|
||||
|
||||
/* Destroy a hash table */
|
||||
static destroy_hash(h)
|
||||
struct hashtbl *h;
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < h->size; i++) {
|
||||
if(h->tbl[i] != NULL) free(h->tbl[i]);
|
||||
}
|
||||
free(h->tbl);
|
||||
free(h);
|
||||
}
|
||||
|
||||
/* Compute hash value for a string */
|
||||
static unsigned hashval(s)
|
||||
register char *s;
|
||||
{
|
||||
register unsigned hv;
|
||||
|
||||
for(hv = 0; *s != '\0'; s++) {
|
||||
hv ^= ((hv << 3) ^ *s);
|
||||
}
|
||||
return(hv);
|
||||
}
|
||||
|
||||
/* Add an element to a hash table */
|
||||
static add_hash(h, el)
|
||||
struct hashtbl *h;
|
||||
char *el;
|
||||
{
|
||||
unsigned hv;
|
||||
char *s;
|
||||
char **old;
|
||||
int i;
|
||||
|
||||
/* Make space if it isn't there already */
|
||||
if(h->entries + 1 > (h->size >> 1)) {
|
||||
old = h->tbl;
|
||||
h->tbl = (char **) calloc(h->size << 1, sizeof(char *));
|
||||
for(i = 0; i < h->size; i++) {
|
||||
if(old[i] != NULL) {
|
||||
hv = hashval(old[i]) % (h->size << 1);
|
||||
while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1);
|
||||
h->tbl[hv] = old[i];
|
||||
}
|
||||
}
|
||||
h->size = h->size << 1;
|
||||
free(old);
|
||||
}
|
||||
|
||||
hv = hashval(el) % h->size;
|
||||
while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size;
|
||||
s = malloc(strlen(el)+1);
|
||||
strcpy(s, el);
|
||||
h->tbl[hv] = s;
|
||||
h->entries++;
|
||||
}
|
||||
|
||||
/* Returns nonzero if el is in h */
|
||||
static check_hash(h, el)
|
||||
struct hashtbl *h;
|
||||
char *el;
|
||||
{
|
||||
unsigned hv;
|
||||
|
||||
for(hv = hashval(el) % h->size;
|
||||
h->tbl[hv] != NULL;
|
||||
hv = (hv + 1) % h->size) {
|
||||
if(!strcmp(h->tbl[hv], el)) return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
struct acl {
|
||||
char filename[LINESIZE]; /* Name of acl file */
|
||||
int fd; /* File descriptor for acl file */
|
||||
struct stat status; /* File status at last read */
|
||||
struct hashtbl *acl; /* Acl entries */
|
||||
};
|
||||
|
||||
static struct acl acl_cache[CACHED_ACLS];
|
||||
|
||||
static int acl_cache_count = 0;
|
||||
static int acl_cache_next = 0;
|
||||
|
||||
/* Returns < 0 if unsuccessful in loading acl */
|
||||
/* Returns index into acl_cache otherwise */
|
||||
/* Note that if acl is already loaded, this is just a lookup */
|
||||
static int acl_load(name)
|
||||
char *name;
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
struct stat s;
|
||||
char buf[MAX_PRINCIPAL_SIZE];
|
||||
char canon[MAX_PRINCIPAL_SIZE];
|
||||
|
||||
/* See if it's there already */
|
||||
for(i = 0; i < acl_cache_count; i++) {
|
||||
if(!strcmp(acl_cache[i].filename, name)
|
||||
&& acl_cache[i].fd >= 0) goto got_it;
|
||||
}
|
||||
|
||||
/* It isn't, load it in */
|
||||
/* maybe there's still room */
|
||||
if(acl_cache_count < CACHED_ACLS) {
|
||||
i = acl_cache_count++;
|
||||
} else {
|
||||
/* No room, clean one out */
|
||||
i = acl_cache_next;
|
||||
acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS;
|
||||
close(acl_cache[i].fd);
|
||||
if(acl_cache[i].acl) {
|
||||
destroy_hash(acl_cache[i].acl);
|
||||
acl_cache[i].acl = (struct hashtbl *) 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the acl */
|
||||
strcpy(acl_cache[i].filename, name);
|
||||
if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
|
||||
/* Force reload */
|
||||
acl_cache[i].acl = (struct hashtbl *) 0;
|
||||
|
||||
got_it:
|
||||
/*
|
||||
* See if the stat matches
|
||||
*
|
||||
* Use stat(), not fstat(), as the file may have been re-created by
|
||||
* acl_add or acl_delete. If this happens, the old inode will have
|
||||
* no changes in the mod-time and the following test will fail.
|
||||
*/
|
||||
if(stat(acl_cache[i].filename, &s) < 0) return(-1);
|
||||
if(acl_cache[i].acl == (struct hashtbl *) 0
|
||||
|| s.st_nlink != acl_cache[i].status.st_nlink
|
||||
|| s.st_mtime != acl_cache[i].status.st_mtime
|
||||
|| s.st_ctime != acl_cache[i].status.st_ctime) {
|
||||
/* Gotta reload */
|
||||
if(acl_cache[i].fd >= 0) close(acl_cache[i].fd);
|
||||
if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
|
||||
if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1);
|
||||
if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl);
|
||||
acl_cache[i].acl = make_hash(ACL_LEN);
|
||||
while(fgets(buf, sizeof(buf), f) != NULL) {
|
||||
nuke_whitespace(buf);
|
||||
acl_canonicalize_principal(buf, canon);
|
||||
add_hash(acl_cache[i].acl, canon);
|
||||
}
|
||||
fclose(f);
|
||||
acl_cache[i].status = s;
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
/* Returns nonzero if it can be determined that acl contains principal */
|
||||
/* Principal is not canonicalized, and no wildcarding is done */
|
||||
acl_exact_match(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
{
|
||||
int idx;
|
||||
|
||||
return((idx = acl_load(acl)) >= 0
|
||||
&& check_hash(acl_cache[idx].acl, principal));
|
||||
}
|
||||
|
||||
/* Returns nonzero if it can be determined that acl contains principal */
|
||||
/* Recognizes wildcards in acl of the form
|
||||
name.*@realm, *.*@realm, and *.*@* */
|
||||
acl_check(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
{
|
||||
char buf[MAX_PRINCIPAL_SIZE];
|
||||
char canon[MAX_PRINCIPAL_SIZE];
|
||||
char *realm;
|
||||
|
||||
acl_canonicalize_principal(principal, canon);
|
||||
|
||||
/* Is it there? */
|
||||
if(acl_exact_match(acl, canon)) return(1);
|
||||
|
||||
/* Try the wildcards */
|
||||
realm = index(canon, REALM_SEP);
|
||||
*index(canon, INST_SEP) = '\0'; /* Chuck the instance */
|
||||
|
||||
sprintf(buf, "%s.*%s", canon, realm);
|
||||
if(acl_exact_match(acl, buf)) return(1);
|
||||
|
||||
sprintf(buf, "*.*%s", realm);
|
||||
if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Adds principal to acl */
|
||||
/* Wildcards are interpreted literally */
|
||||
acl_add(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
{
|
||||
int idx;
|
||||
int i;
|
||||
FILE *new;
|
||||
char canon[MAX_PRINCIPAL_SIZE];
|
||||
|
||||
acl_canonicalize_principal(principal, canon);
|
||||
|
||||
if((new = acl_lock_file(acl)) == NULL) return(-1);
|
||||
if((acl_exact_match(acl, canon))
|
||||
|| (idx = acl_load(acl)) < 0) {
|
||||
acl_abort(acl, new);
|
||||
return(-1);
|
||||
}
|
||||
/* It isn't there yet, copy the file and put it in */
|
||||
for(i = 0; i < acl_cache[idx].acl->size; i++) {
|
||||
if(acl_cache[idx].acl->tbl[i] != NULL) {
|
||||
if(fputs(acl_cache[idx].acl->tbl[i], new) == NULL
|
||||
|| putc('\n', new) != '\n') {
|
||||
acl_abort(acl, new);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fputs(canon, new);
|
||||
putc('\n', new);
|
||||
return(acl_commit(acl, new));
|
||||
}
|
||||
|
||||
/* Removes principal from acl */
|
||||
/* Wildcards are interpreted literally */
|
||||
acl_delete(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
{
|
||||
int idx;
|
||||
int i;
|
||||
FILE *new;
|
||||
char canon[MAX_PRINCIPAL_SIZE];
|
||||
|
||||
acl_canonicalize_principal(principal, canon);
|
||||
|
||||
if((new = acl_lock_file(acl)) == NULL) return(-1);
|
||||
if((!acl_exact_match(acl, canon))
|
||||
|| (idx = acl_load(acl)) < 0) {
|
||||
acl_abort(acl, new);
|
||||
return(-1);
|
||||
}
|
||||
/* It isn't there yet, copy the file and put it in */
|
||||
for(i = 0; i < acl_cache[idx].acl->size; i++) {
|
||||
if(acl_cache[idx].acl->tbl[i] != NULL
|
||||
&& strcmp(acl_cache[idx].acl->tbl[i], canon)) {
|
||||
fputs(acl_cache[idx].acl->tbl[i], new);
|
||||
putc('\n', new);
|
||||
}
|
||||
}
|
||||
return(acl_commit(acl, new));
|
||||
}
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
PROTOTYPE ACL LIBRARY
|
||||
|
||||
Introduction
|
||||
|
||||
An access control list (ACL) is a list of principals, where each
|
||||
principal is is represented by a text string which cannot contain
|
||||
whitespace. The library allows application programs to refer to named
|
||||
access control lists to test membership and to atomically add and
|
||||
delete principals using a natural and intuitive interface. At
|
||||
present, the names of access control lists are required to be Unix
|
||||
filenames, and refer to human-readable Unix files; in the future, when
|
||||
a networked ACL server is implemented, the names may refer to a
|
||||
different namespace specific to the ACL service.
|
||||
|
||||
|
||||
Usage
|
||||
|
||||
cc <files> -lacl -lkrb.
|
||||
|
||||
|
||||
|
||||
Principal Names
|
||||
|
||||
Principal names have the form
|
||||
|
||||
<name>[.<instance>][@<realm>]
|
||||
|
||||
e.g.
|
||||
|
||||
asp
|
||||
asp.root
|
||||
[email protected]
|
||||
[email protected]
|
||||
[email protected]
|
||||
|
||||
It is possible for principals to be underspecified. If instance is
|
||||
missing, it is assumed to be "". If realm is missing, it is assumed
|
||||
to be local_realm. The canonical form contains all of name, instance,
|
||||
and realm; the acl_add and acl_delete routines will always
|
||||
leave the file in that form. Note that the canonical form of
|
||||
[email protected] is actually [email protected].
|
||||
|
||||
|
||||
Routines
|
||||
|
||||
acl_canonicalize_principal(principal, buf)
|
||||
char *principal;
|
||||
char *buf; /*RETVAL*/
|
||||
|
||||
Store the canonical form of principal in buf. Buf must contain enough
|
||||
space to store a principal, given the limits on the sizes of name,
|
||||
instance, and realm specified in /usr/include/krb.h.
|
||||
|
||||
acl_check(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
|
||||
Returns nonzero if principal appears in acl. Returns 0 if principal
|
||||
does not appear in acl, or if an error occurs. Canonicalizes
|
||||
principal before checking, and allows the ACL to contain wildcards.
|
||||
|
||||
acl_exact_match(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
|
||||
Like acl_check, but does no canonicalization or wildcarding.
|
||||
|
||||
acl_add(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
|
||||
Atomically adds principal to acl. Returns 0 if successful, nonzero
|
||||
otherwise. It is considered a failure if principal is already in acl.
|
||||
This routine will canonicalize principal, but will treat wildcards
|
||||
literally.
|
||||
|
||||
acl_delete(acl, principal)
|
||||
char *acl;
|
||||
char *principal;
|
||||
|
||||
Atomically deletes principal from acl. Returns 0 if successful,
|
||||
nonzero otherwise. It is consider a failure if principal is not
|
||||
already in acl. This routine will canonicalize principal, but will
|
||||
treat wildcards literally.
|
||||
|
||||
acl_initialize(acl, mode)
|
||||
char *acl;
|
||||
int mode;
|
||||
|
||||
Initialize acl. If acl file does not exist, creates it with mode
|
||||
mode. If acl exists, removes all members. Returns 0 if successful,
|
||||
nonzero otherwise. WARNING: Mode argument is likely to change with
|
||||
the eventual introduction of an ACL service.
|
||||
|
||||
|
||||
Known problems
|
||||
|
||||
In the presence of concurrency, there is a very small chance that
|
||||
acl_add or acl_delete could report success even though it would have
|
||||
had no effect. This is a necessary side effect of using lock files
|
||||
for concurrency control rather than flock(2), which is not supported
|
||||
by NFS.
|
||||
|
||||
The current implementation caches ACLs in memory in a hash-table
|
||||
format for increased efficiency in checking membership; one effect of
|
||||
the caching scheme is that one file descriptor will be kept open for
|
||||
each ACL cached, up to a maximum of 8.
|
||||
@@ -1,4 +0,0 @@
|
||||
The files in this directory are believed to be exportable.
|
||||
|
||||
-GAWollman
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
LIB= kadm
|
||||
|
||||
SRCS= kadm_err.c kadm_stream.c kadm_supp.c kadm_cli_wrap.c
|
||||
CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/../include -I${KRBOBJDIR} -DPOSIX
|
||||
CLEANFILES+= kadm_err.c kadm_err.h
|
||||
|
||||
kadm_err.c kadm_err.h: kadm_err.et
|
||||
test -e kadm_err.et || ln -s ${.CURDIR}/kadm_err.et .
|
||||
compile_et kadm_err.et
|
||||
|
||||
beforeinstall:
|
||||
-cd ${.CURDIR}; cmp -s kadm.h \
|
||||
${DESTDIR}/usr/include/kerberosIV/kadm.h || \
|
||||
install -c -o ${BINOWN} -g ${BINGRP} -m 444 kadm.h \
|
||||
${DESTDIR}/usr/include/kerberosIV
|
||||
-cd ${.OBJDIR}; cmp -s kadm_err.h \
|
||||
${DESTDIR}/usr/include/kerberosIV/kadm_err.h || \
|
||||
install -c -o ${BINOWN} -g ${BINGRP} -m 444 kadm_err.h \
|
||||
${DESTDIR}/usr/include/kerberosIV
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* $Source: /home/ncvs/src/eBones/libkadm/kadm.h,v $
|
||||
* $Author: wollman $
|
||||
* Header: /afs/athena.mit.edu/astaff/project/kerberos/src/include/RCS/kadm.h,v 4.2 89/09/26 09:15:20 jtkohl Exp
|
||||
*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* Copyright.MIT.
|
||||
*
|
||||
* Definitions for Kerberos administration server & client
|
||||
*/
|
||||
|
||||
#ifndef KADM_DEFS
|
||||
#define KADM_DEFS
|
||||
|
||||
/*
|
||||
* kadm.h
|
||||
* Header file for the fourth attempt at an admin server
|
||||
* Doug Church, December 28, 1989, MIT Project Athena
|
||||
*/
|
||||
|
||||
/* for those broken Unixes without this defined... should be in sys/param.h */
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <krb.h>
|
||||
#include <des.h>
|
||||
|
||||
/* The global structures for the client and server */
|
||||
typedef struct {
|
||||
struct sockaddr_in admin_addr;
|
||||
struct sockaddr_in my_addr;
|
||||
int my_addr_len;
|
||||
int admin_fd; /* file descriptor for link to admin server */
|
||||
char sname[ANAME_SZ]; /* the service name */
|
||||
char sinst[INST_SZ]; /* the services instance */
|
||||
char krbrlm[REALM_SZ];
|
||||
} Kadm_Client;
|
||||
|
||||
typedef struct { /* status of the server, i.e the parameters */
|
||||
int inter; /* Space for command line flags */
|
||||
char *sysfile; /* filename of server */
|
||||
} admin_params; /* Well... it's the admin's parameters */
|
||||
|
||||
/* Largest password length to be supported */
|
||||
#define MAX_KPW_LEN 128
|
||||
|
||||
/* Largest packet the admin server will ever allow itself to return */
|
||||
#define KADM_RET_MAX 2048
|
||||
|
||||
/* That's right, versions are 8 byte strings */
|
||||
#define KADM_VERSTR "KADM0.0A"
|
||||
#define KADM_ULOSE "KYOULOSE" /* sent back when server can't
|
||||
decrypt client's msg */
|
||||
#define KADM_VERSIZE strlen(KADM_VERSTR)
|
||||
|
||||
/* the lookups for the server instances */
|
||||
#define PWSERV_NAME "changepw"
|
||||
#define KADM_SNAME "kerberos_master"
|
||||
#define KADM_SINST "kerberos"
|
||||
|
||||
/* Attributes fields constants and macros */
|
||||
#define ALLOC 2
|
||||
#define RESERVED 3
|
||||
#define DEALLOC 4
|
||||
#define DEACTIVATED 5
|
||||
#define ACTIVE 6
|
||||
|
||||
/* Kadm_vals structure for passing db fields into the server routines */
|
||||
#define FLDSZ 4
|
||||
|
||||
typedef struct {
|
||||
u_char fields[FLDSZ]; /* The active fields in this struct */
|
||||
char name[ANAME_SZ];
|
||||
char instance[INST_SZ];
|
||||
unsigned long key_low;
|
||||
unsigned long key_high;
|
||||
unsigned long exp_date;
|
||||
unsigned short attributes;
|
||||
unsigned char max_life;
|
||||
} Kadm_vals; /* The basic values structure in Kadm */
|
||||
|
||||
/* Kadm_vals structure for passing db fields into the server routines */
|
||||
#define FLDSZ 4
|
||||
|
||||
/* Need to define fields types here */
|
||||
#define KADM_NAME 31
|
||||
#define KADM_INST 30
|
||||
#define KADM_EXPDATE 29
|
||||
#define KADM_ATTR 28
|
||||
#define KADM_MAXLIFE 27
|
||||
#define KADM_DESKEY 26
|
||||
|
||||
/* To set a field entry f in a fields structure d */
|
||||
#define SET_FIELD(f,d) (d[3-(f/8)]|=(1<<(f%8)))
|
||||
|
||||
/* To set a field entry f in a fields structure d */
|
||||
#define CLEAR_FIELD(f,d) (d[3-(f/8)]&=(~(1<<(f%8))))
|
||||
|
||||
/* Is field f in fields structure d */
|
||||
#define IS_FIELD(f,d) (d[3-(f/8)]&(1<<(f%8)))
|
||||
|
||||
/* Various return codes */
|
||||
#define KADM_SUCCESS 0
|
||||
|
||||
#define WILDCARD_STR "*"
|
||||
|
||||
enum acl_types {
|
||||
ADDACL,
|
||||
GETACL,
|
||||
MODACL
|
||||
};
|
||||
|
||||
/* Various opcodes for the admin server's functions */
|
||||
#define CHANGE_PW 2
|
||||
#define ADD_ENT 3
|
||||
#define MOD_ENT 4
|
||||
#define GET_ENT 5
|
||||
|
||||
extern long kdb_get_master_key(); /* XXX should be in krb_db.h */
|
||||
extern long kdb_verify_master_key(); /* XXX ditto */
|
||||
|
||||
extern long krb_mk_priv(), krb_rd_priv(); /* XXX should be in krb.h */
|
||||
extern void krb_set_tkt_string(); /* XXX ditto */
|
||||
|
||||
extern unsigned long quad_cksum(); /* XXX should be in des.h */
|
||||
|
||||
/* XXX This doesn't belong here!!! */
|
||||
char *malloc(), *realloc();
|
||||
#ifdef POSIX
|
||||
typedef void sigtype;
|
||||
#else
|
||||
typedef int sigtype;
|
||||
#endif
|
||||
|
||||
#endif KADM_DEFS
|
||||
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* Copyright.MIT.
|
||||
*
|
||||
* Kerberos administration server client-side routines
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char rcsid_kadm_cli_wrap_c[] =
|
||||
"from: Id: kadm_cli_wrap.c,v 4.6 89/12/30 20:09:45 qjb Exp";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$Id: kadm_cli_wrap.c,v 1.1 1995/01/20 02:02:51 wollman Exp $";
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
* kadm_cli_wrap.c the client side wrapping of the calls to the admin server
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <kadm.h>
|
||||
#include <kadm_err.h>
|
||||
#include <krb_err.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
static Kadm_Client client_parm;
|
||||
|
||||
/* Macros for use in returning data... used in kadm_cli_send */
|
||||
#define RET_N_FREE(r) {clear_secrets(); free((char *)act_st); free((char *)priv_pak); return r;}
|
||||
|
||||
/* Keys for use in the transactions */
|
||||
static des_cblock sess_key; /* to be filled in by kadm_cli_keyd */
|
||||
static Key_schedule sess_sched;
|
||||
|
||||
static
|
||||
clear_secrets()
|
||||
{
|
||||
bzero((char *)sess_key, sizeof(sess_key));
|
||||
bzero((char *)sess_sched, sizeof(sess_sched));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* kadm_init_link
|
||||
* receives : name, inst, realm
|
||||
*
|
||||
* initializes client parm, the Kadm_Client structure which holds the
|
||||
* data about the connection between the server and client, the services
|
||||
* used, the locations and other fun things
|
||||
*/
|
||||
kadm_init_link(n, i, r)
|
||||
char n[];
|
||||
char i[];
|
||||
char r[];
|
||||
{
|
||||
struct servent *sep; /* service we will talk to */
|
||||
struct hostent *hop; /* host we will talk to */
|
||||
char adm_hostname[MAXHOSTNAMELEN];
|
||||
|
||||
(void) init_kadm_err_tbl();
|
||||
(void) init_krb_err_tbl();
|
||||
(void) strcpy(client_parm.sname, n);
|
||||
(void) strcpy(client_parm.sinst, i);
|
||||
(void) strcpy(client_parm.krbrlm, r);
|
||||
client_parm.admin_fd = -1;
|
||||
|
||||
/* set up the admin_addr - fetch name of admin host */
|
||||
if (krb_get_admhst(adm_hostname, client_parm.krbrlm, 1) != KSUCCESS)
|
||||
return KADM_NO_HOST;
|
||||
if ((hop = gethostbyname(adm_hostname)) == NULL)
|
||||
return KADM_UNK_HOST; /* couldnt find the admin servers
|
||||
* address */
|
||||
if ((sep = getservbyname(KADM_SNAME, "tcp")) == NULL)
|
||||
return KADM_NO_SERV; /* couldnt find the admin service */
|
||||
bzero((char *) &client_parm.admin_addr,
|
||||
sizeof(client_parm.admin_addr));
|
||||
client_parm.admin_addr.sin_family = hop->h_addrtype;
|
||||
bcopy((char *) hop->h_addr, (char *) &client_parm.admin_addr.sin_addr,
|
||||
hop->h_length);
|
||||
client_parm.admin_addr.sin_port = sep->s_port;
|
||||
|
||||
return KADM_SUCCESS;
|
||||
} /* procedure kadm_init_link */
|
||||
|
||||
/*
|
||||
* kadm_change_pw
|
||||
* recieves : key
|
||||
*
|
||||
* Replaces the password (i.e. des key) of the caller with that specified in
|
||||
* key. Returns no actual data from the master server, since this is called
|
||||
* by a user
|
||||
*/
|
||||
kadm_change_pw(newkey)
|
||||
des_cblock newkey; /* The DES form of the users key */
|
||||
{
|
||||
int stsize, retc; /* stream size and return code */
|
||||
u_char *send_st; /* send stream */
|
||||
u_char *ret_st;
|
||||
int ret_sz;
|
||||
u_long keytmp;
|
||||
|
||||
if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
|
||||
return(retc);
|
||||
/* possible problem with vts_long on a non-multiple of four boundary */
|
||||
|
||||
stsize = 0; /* start of our output packet */
|
||||
send_st = (u_char *) malloc(1);/* to make it reallocable */
|
||||
send_st[stsize++] = (u_char) CHANGE_PW;
|
||||
|
||||
/* change key to stream */
|
||||
|
||||
bcopy((char *) (((long *) newkey) + 1), (char *) &keytmp, 4);
|
||||
keytmp = htonl(keytmp);
|
||||
stsize += vts_long(keytmp, &send_st, stsize);
|
||||
|
||||
bcopy((char *) newkey, (char *) &keytmp, 4);
|
||||
keytmp = htonl(keytmp);
|
||||
stsize += vts_long(keytmp, &send_st, stsize);
|
||||
|
||||
retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz);
|
||||
free((char *)send_st);
|
||||
if (retc == KADM_SUCCESS) {
|
||||
free((char *)ret_st);
|
||||
}
|
||||
kadm_cli_disconn();
|
||||
return(retc);
|
||||
}
|
||||
|
||||
/*
|
||||
* kadm_add
|
||||
* receives : vals
|
||||
* returns : vals
|
||||
*
|
||||
* Adds and entry containing values to the database returns the values of the
|
||||
* entry, so if you leave certain fields blank you will be able to determine
|
||||
* the default values they are set to
|
||||
*/
|
||||
kadm_add(vals)
|
||||
Kadm_vals *vals;
|
||||
{
|
||||
u_char *st, *st2; /* st will hold the stream of values */
|
||||
int st_len; /* st2 the final stream with opcode */
|
||||
int retc; /* return code from call */
|
||||
u_char *ret_st;
|
||||
int ret_sz;
|
||||
|
||||
if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
|
||||
return(retc);
|
||||
st_len = vals_to_stream(vals, &st);
|
||||
st2 = (u_char *) malloc((unsigned)(1 + st_len));
|
||||
*st2 = (u_char) ADD_ENT; /* here's the opcode */
|
||||
bcopy((char *) st, (char *) st2 + 1, st_len); /* append st on */
|
||||
retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz);
|
||||
free((char *)st);
|
||||
free((char *)st2);
|
||||
if (retc == KADM_SUCCESS) {
|
||||
/* ret_st has vals */
|
||||
if (stream_to_vals(ret_st, vals, ret_sz) < 0)
|
||||
retc = KADM_LENGTH_ERROR;
|
||||
free((char *)ret_st);
|
||||
}
|
||||
kadm_cli_disconn();
|
||||
return(retc);
|
||||
}
|
||||
|
||||
/*
|
||||
* kadm_mod
|
||||
* receives : KTEXT, {values, values}
|
||||
* returns : CKSUM, RETCODE, {values}
|
||||
* acl : su, sms (as register or dealloc)
|
||||
*
|
||||
* Modifies all entries corresponding to the first values so they match the
|
||||
* second values. returns the values for the changed entries in vals2
|
||||
*/
|
||||
kadm_mod(vals1, vals2)
|
||||
Kadm_vals *vals1;
|
||||
Kadm_vals *vals2;
|
||||
{
|
||||
u_char *st, *st2; /* st will hold the stream of values */
|
||||
int st_len, nlen; /* st2 the final stream with opcode */
|
||||
u_char *ret_st;
|
||||
int ret_sz;
|
||||
|
||||
/* nlen is the length of second vals */
|
||||
int retc; /* return code from call */
|
||||
|
||||
if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
|
||||
return(retc);
|
||||
|
||||
st_len = vals_to_stream(vals1, &st);
|
||||
st2 = (u_char *) malloc((unsigned)(1 + st_len));
|
||||
*st2 = (u_char) MOD_ENT; /* here's the opcode */
|
||||
bcopy((char *) st, (char *) st2 + 1, st_len++); /* append st on */
|
||||
free((char *)st);
|
||||
nlen = vals_to_stream(vals2, &st);
|
||||
st2 = (u_char *) realloc((char *) st2, (unsigned)(st_len + nlen));
|
||||
bcopy((char *) st, (char *) st2 + st_len, nlen); /* append st on */
|
||||
retc = kadm_cli_send(st2, st_len + nlen, &ret_st, &ret_sz);
|
||||
free((char *)st);
|
||||
free((char *)st2);
|
||||
if (retc == KADM_SUCCESS) {
|
||||
/* ret_st has vals */
|
||||
if (stream_to_vals(ret_st, vals2, ret_sz) < 0)
|
||||
retc = KADM_LENGTH_ERROR;
|
||||
free((char *)ret_st);
|
||||
}
|
||||
kadm_cli_disconn();
|
||||
return(retc);
|
||||
}
|
||||
|
||||
/*
|
||||
* kadm_get
|
||||
* receives : KTEXT, {values, flags}
|
||||
* returns : CKSUM, RETCODE, {count, values, values, values}
|
||||
* acl : su
|
||||
*
|
||||
* gets the fields requested by flags from all entries matching values returns
|
||||
* this data for each matching recipient, after a count of how many such
|
||||
* matches there were
|
||||
*/
|
||||
kadm_get(vals, fl)
|
||||
Kadm_vals *vals;
|
||||
u_char fl[4];
|
||||
|
||||
{
|
||||
int loop; /* for copying the fields data */
|
||||
u_char *st, *st2; /* st will hold the stream of values */
|
||||
int st_len; /* st2 the final stream with opcode */
|
||||
int retc; /* return code from call */
|
||||
u_char *ret_st;
|
||||
int ret_sz;
|
||||
|
||||
if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
|
||||
return(retc);
|
||||
st_len = vals_to_stream(vals, &st);
|
||||
st2 = (u_char *) malloc((unsigned)(1 + st_len + FLDSZ));
|
||||
*st2 = (u_char) GET_ENT; /* here's the opcode */
|
||||
bcopy((char *) st, (char *) st2 + 1, st_len); /* append st on */
|
||||
for (loop = FLDSZ - 1; loop >= 0; loop--)
|
||||
*(st2 + st_len + FLDSZ - loop) = fl[loop]; /* append the flags */
|
||||
retc = kadm_cli_send(st2, st_len + 1 + FLDSZ, &ret_st, &ret_sz);
|
||||
free((char *)st);
|
||||
free((char *)st2);
|
||||
if (retc == KADM_SUCCESS) {
|
||||
/* ret_st has vals */
|
||||
if (stream_to_vals(ret_st, vals, ret_sz) < 0)
|
||||
retc = KADM_LENGTH_ERROR;
|
||||
free((char *)ret_st);
|
||||
}
|
||||
kadm_cli_disconn();
|
||||
return(retc);
|
||||
}
|
||||
|
||||
/*
|
||||
* kadm_cli_send
|
||||
* recieves : opcode, packet, packet length, serv_name, serv_inst
|
||||
* returns : return code from the packet build, the server, or
|
||||
* something else
|
||||
*
|
||||
* It assembles a packet as follows:
|
||||
* 8 bytes : VERSION STRING
|
||||
* 4 bytes : LENGTH OF MESSAGE DATA and OPCODE
|
||||
* : KTEXT
|
||||
* : OPCODE \
|
||||
* : DATA > Encrypted (with make priv)
|
||||
* : ...... /
|
||||
*
|
||||
* If it builds the packet and it is small enough, then it attempts to open the
|
||||
* connection to the admin server. If the connection is succesfully open
|
||||
* then it sends the data and waits for a reply.
|
||||
*/
|
||||
kadm_cli_send(st_dat, st_siz, ret_dat, ret_siz)
|
||||
u_char *st_dat; /* the actual data */
|
||||
int st_siz; /* length of said data */
|
||||
u_char **ret_dat; /* to give return info */
|
||||
int *ret_siz; /* length of returned info */
|
||||
{
|
||||
int act_len, retdat; /* current offset into packet, return
|
||||
* data */
|
||||
KTEXT_ST authent; /* the authenticator we will build */
|
||||
u_char *act_st; /* the pointer to the complete packet */
|
||||
u_char *priv_pak; /* private version of the packet */
|
||||
int priv_len; /* length of private packet */
|
||||
u_long cksum; /* checksum of the packet */
|
||||
MSG_DAT mdat;
|
||||
u_char *return_dat;
|
||||
|
||||
act_st = (u_char *) malloc(KADM_VERSIZE); /* verstr stored first */
|
||||
(void) strncpy((char *)act_st, KADM_VERSTR, KADM_VERSIZE);
|
||||
act_len = KADM_VERSIZE;
|
||||
|
||||
if ((retdat = kadm_cli_keyd(sess_key, sess_sched)) != KADM_SUCCESS) {
|
||||
free((char *)act_st);
|
||||
return retdat; /* couldnt get key working */
|
||||
}
|
||||
priv_pak = (u_char *) malloc((unsigned)(st_siz + 200));
|
||||
/* 200 bytes for extra info case */
|
||||
if ((priv_len = krb_mk_priv(st_dat, priv_pak, (u_long)st_siz,
|
||||
sess_sched, sess_key, &client_parm.my_addr,
|
||||
&client_parm.admin_addr)) < 0)
|
||||
RET_N_FREE(KADM_NO_ENCRYPT); /* whoops... we got a lose
|
||||
* here */
|
||||
/* here is the length of priv data. receiver calcs
|
||||
size of authenticator by subtracting vno size, priv size, and
|
||||
sizeof(u_long) (for the size indication) from total size */
|
||||
|
||||
act_len += vts_long((u_long) priv_len, &act_st, act_len);
|
||||
#ifdef NOENCRYPTION
|
||||
cksum = 0;
|
||||
#else
|
||||
cksum = quad_cksum(priv_pak, (u_long *)0, (long)priv_len, 0,
|
||||
sess_key);
|
||||
#endif
|
||||
if (retdat = krb_mk_req(&authent, client_parm.sname, client_parm.sinst,
|
||||
client_parm.krbrlm, (long)cksum)) {
|
||||
/* authenticator? */
|
||||
RET_N_FREE(retdat + krb_err_base);
|
||||
}
|
||||
|
||||
act_st = (u_char *) realloc((char *) act_st,
|
||||
(unsigned) (act_len + authent.length
|
||||
+ priv_len));
|
||||
if (!act_st) {
|
||||
clear_secrets();
|
||||
free((char *)priv_pak);
|
||||
return(KADM_NOMEM);
|
||||
}
|
||||
bcopy((char *) authent.dat, (char *) act_st + act_len, authent.length);
|
||||
bcopy((char *) priv_pak, (char *) act_st + act_len + authent.length,
|
||||
priv_len);
|
||||
free((char *)priv_pak);
|
||||
if ((retdat = kadm_cli_out(act_st,
|
||||
act_len + authent.length + priv_len,
|
||||
ret_dat, ret_siz)) != KADM_SUCCESS)
|
||||
RET_N_FREE(retdat);
|
||||
free((char *)act_st);
|
||||
#define RET_N_FREE2(r) {free((char *)*ret_dat); clear_secrets(); return(r);}
|
||||
|
||||
/* first see if it's a YOULOUSE */
|
||||
if ((*ret_siz >= KADM_VERSIZE) &&
|
||||
!strncmp(KADM_ULOSE, (char *)*ret_dat, KADM_VERSIZE)) {
|
||||
u_long errcode;
|
||||
/* it's a youlose packet */
|
||||
if (*ret_siz < KADM_VERSIZE + sizeof(u_long))
|
||||
RET_N_FREE2(KADM_BAD_VER);
|
||||
bcopy((char *)(*ret_dat) + KADM_VERSIZE, (char *)&errcode,
|
||||
sizeof(u_long));
|
||||
retdat = (int) ntohl(errcode);
|
||||
RET_N_FREE2(retdat);
|
||||
}
|
||||
/* need to decode the ret_dat */
|
||||
if (retdat = krb_rd_priv(*ret_dat, (u_long)*ret_siz, sess_sched,
|
||||
sess_key, &client_parm.admin_addr,
|
||||
&client_parm.my_addr, &mdat))
|
||||
RET_N_FREE2(retdat+krb_err_base);
|
||||
if (mdat.app_length < KADM_VERSIZE + 4)
|
||||
/* too short! */
|
||||
RET_N_FREE2(KADM_BAD_VER);
|
||||
if (strncmp((char *)mdat.app_data, KADM_VERSTR, KADM_VERSIZE))
|
||||
/* bad version */
|
||||
RET_N_FREE2(KADM_BAD_VER);
|
||||
bcopy((char *)mdat.app_data+KADM_VERSIZE,
|
||||
(char *)&retdat, sizeof(u_long));
|
||||
retdat = ntohl((u_long)retdat);
|
||||
if (!(return_dat = (u_char *)malloc((unsigned)(mdat.app_length -
|
||||
KADM_VERSIZE - sizeof(u_long)))))
|
||||
RET_N_FREE2(KADM_NOMEM);
|
||||
bcopy((char *) mdat.app_data + KADM_VERSIZE + sizeof(u_long),
|
||||
(char *)return_dat,
|
||||
(int)mdat.app_length - KADM_VERSIZE - sizeof(u_long));
|
||||
free((char *)*ret_dat);
|
||||
clear_secrets();
|
||||
*ret_dat = return_dat;
|
||||
*ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(u_long);
|
||||
return retdat;
|
||||
}
|
||||
|
||||
/* takes in the sess_key and key_schedule and sets them appropriately */
|
||||
kadm_cli_keyd(s_k, s_s)
|
||||
des_cblock s_k; /* session key */
|
||||
des_key_schedule s_s; /* session key schedule */
|
||||
{
|
||||
CREDENTIALS cred; /* to get key data */
|
||||
int stat;
|
||||
|
||||
/* want .sname and .sinst here.... */
|
||||
if (stat = krb_get_cred(client_parm.sname, client_parm.sinst,
|
||||
client_parm.krbrlm, &cred))
|
||||
return stat + krb_err_base;
|
||||
bcopy((char *) cred.session, (char *) s_k, sizeof(des_cblock));
|
||||
bzero((char *) cred.session, sizeof(des_cblock));
|
||||
#ifdef NOENCRYPTION
|
||||
bzero(s_s, sizeof(des_key_schedule));
|
||||
#else
|
||||
if (stat = key_sched(s_k,s_s))
|
||||
return(stat+krb_err_base);
|
||||
#endif
|
||||
return KADM_SUCCESS;
|
||||
} /* This code "works" */
|
||||
|
||||
static sigtype (*opipe)();
|
||||
|
||||
kadm_cli_conn()
|
||||
{ /* this connects and sets my_addr */
|
||||
int on = 1;
|
||||
|
||||
if ((client_parm.admin_fd =
|
||||
socket(client_parm.admin_addr.sin_family, SOCK_STREAM,0)) < 0)
|
||||
return KADM_NO_SOCK; /* couldnt create the socket */
|
||||
if (connect(client_parm.admin_fd,
|
||||
(struct sockaddr *) & client_parm.admin_addr,
|
||||
sizeof(client_parm.admin_addr))) {
|
||||
(void) close(client_parm.admin_fd);
|
||||
client_parm.admin_fd = -1;
|
||||
return KADM_NO_CONN; /* couldnt get the connect */
|
||||
}
|
||||
opipe = signal(SIGPIPE, SIG_IGN);
|
||||
client_parm.my_addr_len = sizeof(client_parm.my_addr);
|
||||
if (getsockname(client_parm.admin_fd,
|
||||
(struct sockaddr *) & client_parm.my_addr,
|
||||
&client_parm.my_addr_len) < 0) {
|
||||
(void) close(client_parm.admin_fd);
|
||||
client_parm.admin_fd = -1;
|
||||
(void) signal(SIGPIPE, opipe);
|
||||
return KADM_NO_HERE; /* couldnt find out who we are */
|
||||
}
|
||||
if (setsockopt(client_parm.admin_fd, SOL_SOCKET, SO_KEEPALIVE, &on,
|
||||
sizeof(on)) < 0) {
|
||||
(void) close(client_parm.admin_fd);
|
||||
client_parm.admin_fd = -1;
|
||||
(void) signal(SIGPIPE, opipe);
|
||||
return KADM_NO_CONN; /* XXX */
|
||||
}
|
||||
return KADM_SUCCESS;
|
||||
}
|
||||
|
||||
kadm_cli_disconn()
|
||||
{
|
||||
(void) close(client_parm.admin_fd);
|
||||
(void) signal(SIGPIPE, opipe);
|
||||
return;
|
||||
}
|
||||
|
||||
kadm_cli_out(dat, dat_len, ret_dat, ret_siz)
|
||||
u_char *dat;
|
||||
int dat_len;
|
||||
u_char **ret_dat;
|
||||
int *ret_siz;
|
||||
{
|
||||
extern int errno;
|
||||
u_short dlen;
|
||||
int retval;
|
||||
|
||||
dlen = (u_short) dat_len;
|
||||
|
||||
if (dat_len != (int)dlen)
|
||||
return (KADM_NO_ROOM);
|
||||
|
||||
dlen = htons(dlen);
|
||||
if (krb_net_write(client_parm.admin_fd, (char *) &dlen,
|
||||
sizeof(u_short)) < 0)
|
||||
return (errno); /* XXX */
|
||||
|
||||
if (krb_net_write(client_parm.admin_fd, (char *) dat, dat_len) < 0)
|
||||
return (errno); /* XXX */
|
||||
|
||||
if (retval = krb_net_read(client_parm.admin_fd, (char *) &dlen,
|
||||
sizeof(u_short)) != sizeof(u_short)) {
|
||||
if (retval < 0)
|
||||
return(errno); /* XXX */
|
||||
else
|
||||
return(EPIPE); /* short read ! */
|
||||
}
|
||||
|
||||
dlen = ntohs(dlen);
|
||||
*ret_dat = (u_char *)malloc((unsigned)dlen);
|
||||
if (!*ret_dat)
|
||||
return(KADM_NOMEM);
|
||||
|
||||
if (retval = krb_net_read(client_parm.admin_fd, (char *) *ret_dat,
|
||||
(int) dlen) != dlen) {
|
||||
if (retval < 0)
|
||||
return(errno); /* XXX */
|
||||
else
|
||||
return(EPIPE); /* short read ! */
|
||||
}
|
||||
*ret_siz = (int) dlen;
|
||||
return KADM_SUCCESS;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
# $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v $
|
||||
# $Author: jtkohl $
|
||||
# $Header: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v 4.0 89/01/24 15:16:10 jtkohl Exp $
|
||||
# Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
#
|
||||
# For copying and distribution information, please see the file
|
||||
# <mit-copyright.h>.
|
||||
#
|
||||
# Kerberos administration server error table
|
||||
#
|
||||
et kadm
|
||||
|
||||
# KADM_SUCCESS, as all success codes should be, is zero
|
||||
|
||||
ec KADM_RCSID, "$Header: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kadm_err.et,v 4.0 89/01/24 15:16:10 jtkohl Exp $"
|
||||
# /* Building and unbuilding the packet errors */
|
||||
ec KADM_NO_REALM, "Cannot fetch local realm"
|
||||
ec KADM_NO_CRED, "Unable to fetch credentials"
|
||||
ec KADM_BAD_KEY, "Bad key supplied"
|
||||
ec KADM_NO_ENCRYPT, "Can't encrypt data"
|
||||
ec KADM_NO_AUTH, "Cannot encode/decode authentication info"
|
||||
ec KADM_WRONG_REALM, "Principal attemping change is in wrong realm"
|
||||
ec KADM_NO_ROOM, "Packet is too large"
|
||||
ec KADM_BAD_VER, "Version number is incorrect"
|
||||
ec KADM_BAD_CHK, "Checksum does not match"
|
||||
ec KADM_NO_READ, "Unsealing private data failed"
|
||||
ec KADM_NO_OPCODE, "Unsupported operation"
|
||||
ec KADM_NO_HOST, "Could not find administrating host"
|
||||
ec KADM_UNK_HOST, "Administrating host name is unknown"
|
||||
ec KADM_NO_SERV, "Could not find service name in services database"
|
||||
ec KADM_NO_SOCK, "Could not create socket"
|
||||
ec KADM_NO_CONN, "Could not connect to server"
|
||||
ec KADM_NO_HERE, "Could not fetch local socket address"
|
||||
ec KADM_NO_MAST, "Could not fetch master key"
|
||||
ec KADM_NO_VERI, "Could not verify master key"
|
||||
|
||||
# /* From the server side routines */
|
||||
ec KADM_INUSE, "Entry already exists in database"
|
||||
ec KADM_UK_SERROR, "Database store error"
|
||||
ec KADM_UK_RERROR, "Database read error"
|
||||
ec KADM_UNAUTH, "Insufficient access to perform requested operation"
|
||||
# KADM_DATA isn't really an error, but...
|
||||
ec KADM_DATA, "Data is available for return to client"
|
||||
ec KADM_NOENTRY, "No such entry in the database"
|
||||
|
||||
ec KADM_NOMEM, "Memory exhausted"
|
||||
ec KADM_NO_HOSTNAME, "Could not fetch system hostname"
|
||||
ec KADM_NO_BIND, "Could not bind port"
|
||||
ec KADM_LENGTH_ERROR, "Length mismatch problem"
|
||||
ec KADM_ILL_WILDCARD, "Illegal use of wildcard"
|
||||
|
||||
ec KADM_DB_INUSE, "Database is locked or in use--try again later"
|
||||
end
|
||||
@@ -1,273 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* Copyright.MIT.
|
||||
*
|
||||
* Stream conversion functions for Kerberos administration server
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char rcsid_kadm_stream_c[] =
|
||||
"Header: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/kadm/RCS/kadm_stream.c,v 4.2 89/09/26 09:20:48 jtkohl Exp ";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$Id: kadm_stream.c,v 1.1 1995/01/20 02:02:53 wollman Exp $";
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
kadm_stream.c
|
||||
this holds the stream support routines for the kerberos administration server
|
||||
|
||||
vals_to_stream: converts a vals struct to a stream for transmission
|
||||
internals build_field_header, vts_[string, char, long, short]
|
||||
stream_to_vals: converts a stream to a vals struct
|
||||
internals check_field_header, stv_[string, char, long, short]
|
||||
error: prints out a kadm error message, returns
|
||||
fatal: prints out a kadm fatal error message, exits
|
||||
*/
|
||||
|
||||
#include "kadm.h"
|
||||
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
/*
|
||||
vals_to_stream
|
||||
recieves : kadm_vals *, u_char *
|
||||
returns : a realloced and filled in u_char *
|
||||
|
||||
this function creates a byte-stream representation of the kadm_vals structure
|
||||
*/
|
||||
vals_to_stream(dt_in, dt_out)
|
||||
Kadm_vals *dt_in;
|
||||
u_char **dt_out;
|
||||
{
|
||||
int vsloop, stsize; /* loop counter, stream size */
|
||||
|
||||
stsize = build_field_header(dt_in->fields, dt_out);
|
||||
for (vsloop=31; vsloop>=0; vsloop--)
|
||||
if (IS_FIELD(vsloop,dt_in->fields)) {
|
||||
switch (vsloop) {
|
||||
case KADM_NAME:
|
||||
stsize+=vts_string(dt_in->name, dt_out, stsize);
|
||||
break;
|
||||
case KADM_INST:
|
||||
stsize+=vts_string(dt_in->instance, dt_out, stsize);
|
||||
break;
|
||||
case KADM_EXPDATE:
|
||||
stsize+=vts_long(dt_in->exp_date, dt_out, stsize);
|
||||
break;
|
||||
case KADM_ATTR:
|
||||
stsize+=vts_short(dt_in->attributes, dt_out, stsize);
|
||||
break;
|
||||
case KADM_MAXLIFE:
|
||||
stsize+=vts_char(dt_in->max_life, dt_out, stsize);
|
||||
break;
|
||||
case KADM_DESKEY:
|
||||
stsize+=vts_long(dt_in->key_high, dt_out, stsize);
|
||||
stsize+=vts_long(dt_in->key_low, dt_out, stsize);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(stsize);
|
||||
}
|
||||
|
||||
build_field_header(cont, st)
|
||||
u_char *cont; /* container for fields data */
|
||||
u_char **st; /* stream */
|
||||
{
|
||||
*st = (u_char *) malloc (4);
|
||||
bcopy((char *) cont, (char *) *st, 4);
|
||||
return 4; /* return pointer to current stream location */
|
||||
}
|
||||
|
||||
vts_string(dat, st, loc)
|
||||
char *dat; /* a string to put on the stream */
|
||||
u_char **st; /* base pointer to the stream */
|
||||
int loc; /* offset into the stream for current data */
|
||||
{
|
||||
*st = (u_char *) realloc ((char *)*st, (unsigned) (loc + strlen(dat) + 1));
|
||||
bcopy(dat, (char *)(*st + loc), strlen(dat)+1);
|
||||
return strlen(dat)+1;
|
||||
}
|
||||
|
||||
vts_short(dat, st, loc)
|
||||
u_short dat; /* the attributes field */
|
||||
u_char **st; /* a base pointer to the stream */
|
||||
int loc; /* offset into the stream for current data */
|
||||
{
|
||||
u_short temp; /* to hold the net order short */
|
||||
|
||||
temp = htons(dat); /* convert to network order */
|
||||
*st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_short)));
|
||||
bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_short));
|
||||
return sizeof(u_short);
|
||||
}
|
||||
|
||||
vts_long(dat, st, loc)
|
||||
u_long dat; /* the attributes field */
|
||||
u_char **st; /* a base pointer to the stream */
|
||||
int loc; /* offset into the stream for current data */
|
||||
{
|
||||
u_long temp; /* to hold the net order short */
|
||||
|
||||
temp = htonl(dat); /* convert to network order */
|
||||
*st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_long)));
|
||||
bcopy((char *) &temp, (char *)(*st + loc), sizeof(u_long));
|
||||
return sizeof(u_long);
|
||||
}
|
||||
|
||||
|
||||
vts_char(dat, st, loc)
|
||||
u_char dat; /* the attributes field */
|
||||
u_char **st; /* a base pointer to the stream */
|
||||
int loc; /* offset into the stream for current data */
|
||||
{
|
||||
*st = (u_char *) realloc ((char *)*st, (unsigned)(loc + sizeof(u_char)));
|
||||
(*st)[loc] = (u_char) dat;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
stream_to_vals
|
||||
recieves : u_char *, kadm_vals *
|
||||
returns : a kadm_vals filled in according to u_char *
|
||||
|
||||
this decodes a byte stream represntation of a vals struct into kadm_vals
|
||||
*/
|
||||
stream_to_vals(dt_in, dt_out, maxlen)
|
||||
u_char *dt_in;
|
||||
Kadm_vals *dt_out;
|
||||
int maxlen; /* max length to use */
|
||||
{
|
||||
register int vsloop, stsize; /* loop counter, stream size */
|
||||
register int status;
|
||||
|
||||
bzero((char *) dt_out, sizeof(*dt_out));
|
||||
|
||||
stsize = check_field_header(dt_in, dt_out->fields, maxlen);
|
||||
if (stsize < 0)
|
||||
return(-1);
|
||||
for (vsloop=31; vsloop>=0; vsloop--)
|
||||
if (IS_FIELD(vsloop,dt_out->fields))
|
||||
switch (vsloop) {
|
||||
case KADM_NAME:
|
||||
if ((status = stv_string(dt_in, dt_out->name, stsize,
|
||||
sizeof(dt_out->name), maxlen)) < 0)
|
||||
return(-1);
|
||||
stsize += status;
|
||||
break;
|
||||
case KADM_INST:
|
||||
if ((status = stv_string(dt_in, dt_out->instance, stsize,
|
||||
sizeof(dt_out->instance), maxlen)) < 0)
|
||||
return(-1);
|
||||
stsize += status;
|
||||
break;
|
||||
case KADM_EXPDATE:
|
||||
if ((status = stv_long(dt_in, &dt_out->exp_date, stsize,
|
||||
maxlen)) < 0)
|
||||
return(-1);
|
||||
stsize += status;
|
||||
break;
|
||||
case KADM_ATTR:
|
||||
if ((status = stv_short(dt_in, &dt_out->attributes, stsize,
|
||||
maxlen)) < 0)
|
||||
return(-1);
|
||||
stsize += status;
|
||||
break;
|
||||
case KADM_MAXLIFE:
|
||||
if ((status = stv_char(dt_in, &dt_out->max_life, stsize,
|
||||
maxlen)) < 0)
|
||||
return(-1);
|
||||
stsize += status;
|
||||
break;
|
||||
case KADM_DESKEY:
|
||||
if ((status = stv_long(dt_in, &dt_out->key_high, stsize,
|
||||
maxlen)) < 0)
|
||||
return(-1);
|
||||
stsize += status;
|
||||
if ((status = stv_long(dt_in, &dt_out->key_low, stsize,
|
||||
maxlen)) < 0)
|
||||
return(-1);
|
||||
stsize += status;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return stsize;
|
||||
}
|
||||
|
||||
check_field_header(st, cont, maxlen)
|
||||
u_char *st; /* stream */
|
||||
u_char *cont; /* container for fields data */
|
||||
int maxlen;
|
||||
{
|
||||
if (4 > maxlen)
|
||||
return(-1);
|
||||
bcopy((char *) st, (char *) cont, 4);
|
||||
return 4; /* return pointer to current stream location */
|
||||
}
|
||||
|
||||
stv_string(st, dat, loc, stlen, maxlen)
|
||||
register u_char *st; /* base pointer to the stream */
|
||||
char *dat; /* a string to read from the stream */
|
||||
register int loc; /* offset into the stream for current data */
|
||||
int stlen; /* max length of string to copy in */
|
||||
int maxlen; /* max length of input stream */
|
||||
{
|
||||
int maxcount; /* max count of chars to copy */
|
||||
|
||||
maxcount = min(maxlen - loc, stlen);
|
||||
|
||||
(void) strncpy(dat, (char *)st + loc, maxcount);
|
||||
|
||||
if (dat[maxcount-1]) /* not null-term --> not enuf room */
|
||||
return(-1);
|
||||
return strlen(dat)+1;
|
||||
}
|
||||
|
||||
stv_short(st, dat, loc, maxlen)
|
||||
u_char *st; /* a base pointer to the stream */
|
||||
u_short *dat; /* the attributes field */
|
||||
int loc; /* offset into the stream for current data */
|
||||
int maxlen;
|
||||
{
|
||||
u_short temp; /* to hold the net order short */
|
||||
|
||||
if (loc + sizeof(u_short) > maxlen)
|
||||
return(-1);
|
||||
bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_short));
|
||||
*dat = ntohs(temp); /* convert to network order */
|
||||
return sizeof(u_short);
|
||||
}
|
||||
|
||||
stv_long(st, dat, loc, maxlen)
|
||||
u_char *st; /* a base pointer to the stream */
|
||||
u_long *dat; /* the attributes field */
|
||||
int loc; /* offset into the stream for current data */
|
||||
int maxlen; /* maximum length of st */
|
||||
{
|
||||
u_long temp; /* to hold the net order short */
|
||||
|
||||
if (loc + sizeof(u_long) > maxlen)
|
||||
return(-1);
|
||||
bcopy((char *)((u_long)st+(u_long)loc), (char *) &temp, sizeof(u_long));
|
||||
*dat = ntohl(temp); /* convert to network order */
|
||||
return sizeof(u_long);
|
||||
}
|
||||
|
||||
stv_char(st, dat, loc, maxlen)
|
||||
u_char *st; /* a base pointer to the stream */
|
||||
u_char *dat; /* the attributes field */
|
||||
int loc; /* offset into the stream for current data */
|
||||
int maxlen;
|
||||
{
|
||||
if (loc + 1 > maxlen)
|
||||
return(-1);
|
||||
*dat = *(st + loc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* Copyright.MIT.
|
||||
*
|
||||
* Support functions for Kerberos administration server & clients
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char rcsid_kadm_supp_c[] =
|
||||
"Header: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/kadm/RCS/kadm_supp.c,v 4.1 89/09/26 09:21:07 jtkohl Exp ";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$Id: kadm_supp.c,v 1.1 1995/01/20 02:02:54 wollman Exp $";
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
kadm_supp.c
|
||||
this holds the support routines for the kerberos administration server
|
||||
|
||||
error: prints out a kadm error message, returns
|
||||
fatal: prints out a kadm fatal error message, exits
|
||||
prin_vals: prints out data associated with a Principal in the vals
|
||||
structure
|
||||
*/
|
||||
|
||||
#include "kadm.h"
|
||||
#include "krb_db.h"
|
||||
|
||||
/*
|
||||
prin_vals:
|
||||
recieves : a vals structure
|
||||
*/
|
||||
prin_vals(vals)
|
||||
Kadm_vals *vals;
|
||||
{
|
||||
printf("Info in Database for %s.%s:\n", vals->name, vals->instance);
|
||||
printf(" Max Life: %d Exp Date: %s\n",vals->max_life,
|
||||
asctime(localtime((long *)&vals->exp_date)));
|
||||
printf(" Attribs: %.2x key: %u %u\n",vals->attributes,
|
||||
vals->key_low, vals->key_high);
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
nierror(s)
|
||||
int s;
|
||||
{
|
||||
extern char *error_message();
|
||||
printf("Kerberos admin server loses..... %s\n",error_message(s));
|
||||
return(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* kadm_prin_to_vals takes a fields arguments, a Kadm_vals and a Principal,
|
||||
it copies the fields in Principal specified by fields into Kadm_vals,
|
||||
i.e from old to new */
|
||||
|
||||
kadm_prin_to_vals(fields, new, old)
|
||||
u_char fields[FLDSZ];
|
||||
Kadm_vals *new;
|
||||
Principal *old;
|
||||
{
|
||||
bzero((char *)new, sizeof(*new));
|
||||
if (IS_FIELD(KADM_NAME,fields)) {
|
||||
(void) strncpy(new->name, old->name, ANAME_SZ);
|
||||
SET_FIELD(KADM_NAME, new->fields);
|
||||
}
|
||||
if (IS_FIELD(KADM_INST,fields)) {
|
||||
(void) strncpy(new->instance, old->instance, INST_SZ);
|
||||
SET_FIELD(KADM_INST, new->fields);
|
||||
}
|
||||
if (IS_FIELD(KADM_EXPDATE,fields)) {
|
||||
new->exp_date = old->exp_date;
|
||||
SET_FIELD(KADM_EXPDATE, new->fields);
|
||||
}
|
||||
if (IS_FIELD(KADM_ATTR,fields)) {
|
||||
new->attributes = old->attributes;
|
||||
SET_FIELD(KADM_MAXLIFE, new->fields);
|
||||
}
|
||||
if (IS_FIELD(KADM_MAXLIFE,fields)) {
|
||||
new->max_life = old->max_life;
|
||||
SET_FIELD(KADM_MAXLIFE, new->fields);
|
||||
}
|
||||
if (IS_FIELD(KADM_DESKEY,fields)) {
|
||||
new->key_low = old->key_low;
|
||||
new->key_high = old->key_high;
|
||||
SET_FIELD(KADM_DESKEY, new->fields);
|
||||
}
|
||||
}
|
||||
|
||||
kadm_vals_to_prin(fields, new, old)
|
||||
u_char fields[FLDSZ];
|
||||
Principal *new;
|
||||
Kadm_vals *old;
|
||||
{
|
||||
|
||||
bzero((char *)new, sizeof(*new));
|
||||
if (IS_FIELD(KADM_NAME,fields))
|
||||
(void) strncpy(new->name, old->name, ANAME_SZ);
|
||||
if (IS_FIELD(KADM_INST,fields))
|
||||
(void) strncpy(new->instance, old->instance, INST_SZ);
|
||||
if (IS_FIELD(KADM_EXPDATE,fields))
|
||||
new->exp_date = old->exp_date;
|
||||
if (IS_FIELD(KADM_ATTR,fields))
|
||||
new->attributes = old->attributes;
|
||||
if (IS_FIELD(KADM_MAXLIFE,fields))
|
||||
new->max_life = old->max_life;
|
||||
if (IS_FIELD(KADM_DESKEY,fields)) {
|
||||
new->key_low = old->key_low;
|
||||
new->key_high = old->key_high;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
|
||||
# $Id: Makefile,v 1.3 1994/09/09 21:43:41 g89r4222 Exp $
|
||||
|
||||
SHLIB_MAJOR= 2
|
||||
SHLIB_MINOR= 0
|
||||
|
||||
LIB= kdb
|
||||
CFLAGS+=-DKERBEROS -DDEBUG -I${.CURDIR}/../include
|
||||
SRCS= krb_cache.c krb_dbm.c krb_kdb_utils.c krb_lib.c print_princ.c
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* This is where a cache would be implemented, if it were necessary.
|
||||
*
|
||||
* from: krb_cache.c,v 4.5 89/01/24 18:12:34 jon Exp $
|
||||
* $Id: krb_cache.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: krb_cache.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <strings.h>
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <krb_db.h>
|
||||
|
||||
extern char *strncpy();
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int debug;
|
||||
extern long kerb_debug;
|
||||
#endif
|
||||
static init = 0;
|
||||
|
||||
/*
|
||||
* initialization routine for cache
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_cache_init()
|
||||
{
|
||||
init = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* look up a principal in the cache returns number of principals found
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_cache_get_principal(serv, inst, principal, max)
|
||||
char *serv; /* could have wild card */
|
||||
char *inst; /* could have wild card */
|
||||
Principal *principal;
|
||||
unsigned int max; /* max number of name structs to return */
|
||||
|
||||
{
|
||||
int found = 0;
|
||||
u_long i;
|
||||
|
||||
if (!init)
|
||||
kerb_cache_init();
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2)
|
||||
fprintf(stderr, "cache_get_principal for %s %s max = %d\n",
|
||||
serv, inst, max);
|
||||
#endif DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2) {
|
||||
if (found) {
|
||||
fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
|
||||
serv, inst, principal->name, principal->instance);
|
||||
} else {
|
||||
fprintf(stderr, "cache %s %s not found\n", serv,
|
||||
inst);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (found);
|
||||
}
|
||||
|
||||
/*
|
||||
* insert/replace a principal in the cache returns number of principals
|
||||
* inserted
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_cache_put_principal(principal, max)
|
||||
Principal *principal;
|
||||
unsigned int max; /* max number of principal structs to
|
||||
* insert */
|
||||
|
||||
{
|
||||
int found = 0;
|
||||
u_long i;
|
||||
int count = 0;
|
||||
|
||||
if (!init)
|
||||
kerb_cache_init();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2) {
|
||||
fprintf(stderr, "kerb_cache_put_principal max = %d",
|
||||
max);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2)
|
||||
fprintf(stderr, "\n %s %s",
|
||||
principal->name, principal->instance);
|
||||
#endif
|
||||
/* DO IT */
|
||||
count++;
|
||||
principal++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* look up a dba in the cache returns number of dbas found
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_cache_get_dba(serv, inst, dba, max)
|
||||
char *serv; /* could have wild card */
|
||||
char *inst; /* could have wild card */
|
||||
Dba *dba;
|
||||
unsigned int max; /* max number of name structs to return */
|
||||
|
||||
{
|
||||
int found = 0;
|
||||
u_long i;
|
||||
|
||||
if (!init)
|
||||
kerb_cache_init();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2)
|
||||
fprintf(stderr, "cache_get_dba for %s %s max = %d\n",
|
||||
serv, inst, max);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2) {
|
||||
if (found) {
|
||||
fprintf(stderr, "cache get %s %s found %s %s sid = %d\n",
|
||||
serv, inst, dba->name, dba->instance);
|
||||
} else {
|
||||
fprintf(stderr, "cache %s %s not found\n", serv, inst);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (found);
|
||||
}
|
||||
|
||||
/*
|
||||
* insert/replace a dba in the cache returns number of dbas inserted
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_cache_put_dba(dba, max)
|
||||
Dba *dba;
|
||||
unsigned int max; /* max number of dba structs to insert */
|
||||
|
||||
{
|
||||
int found = 0;
|
||||
u_long i;
|
||||
int count = 0;
|
||||
|
||||
if (!init)
|
||||
kerb_cache_init();
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2) {
|
||||
fprintf(stderr, "kerb_cache_put_dba max = %d", max);
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < max; i++) {
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2)
|
||||
fprintf(stderr, "\n %s %s",
|
||||
dba->name, dba->instance);
|
||||
#endif
|
||||
/* DO IT */
|
||||
count++;
|
||||
dba++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
This file is now obsolete.
|
||||
@@ -1,755 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: krb_dbm.c,v 4.9 89/04/18 16:15:13 wesommer Exp $
|
||||
* $Id: krb_dbm.c,v 1.2 1995/01/25 19:45:25 ache Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: krb_dbm.c,v 1.2 1995/01/25 19:45:25 ache Exp $";
|
||||
#endif lint
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define NDBM
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/errno.h>
|
||||
#include <strings.h>
|
||||
#include <des.h>
|
||||
#include <sys/file.h>
|
||||
#ifdef NDBM
|
||||
#include <ndbm.h>
|
||||
#else /*NDBM*/
|
||||
#include <dbm.h>
|
||||
#endif /*NDBM*/
|
||||
/* before krb_db.h */
|
||||
#include <krb.h>
|
||||
#include <krb_db.h>
|
||||
|
||||
#define KERB_DB_MAX_RETRY 5
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int debug;
|
||||
extern long kerb_debug;
|
||||
extern char *progname;
|
||||
#endif
|
||||
extern char *malloc();
|
||||
extern int errno;
|
||||
|
||||
static init = 0;
|
||||
static char default_db_name[] = DBM_FILE;
|
||||
static char *current_db_name = default_db_name;
|
||||
static void encode_princ_key(), decode_princ_key();
|
||||
static void encode_princ_contents(), decode_princ_contents();
|
||||
static void kerb_dbl_fini();
|
||||
static int kerb_dbl_lock();
|
||||
static void kerb_dbl_unlock();
|
||||
|
||||
static struct timeval timestamp;/* current time of request */
|
||||
static int non_blocking = 0;
|
||||
|
||||
/*
|
||||
* This module contains all of the code which directly interfaces to
|
||||
* the underlying representation of the Kerberos database; this
|
||||
* implementation uses a DBM or NDBM indexed "file" (actually
|
||||
* implemented as two separate files) to store the relations, plus a
|
||||
* third file as a semaphore to allow the database to be replaced out
|
||||
* from underneath the KDC server.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Locking:
|
||||
*
|
||||
* There are two distinct locking protocols used. One is designed to
|
||||
* lock against processes (the admin_server, for one) which make
|
||||
* incremental changes to the database; the other is designed to lock
|
||||
* against utilities (kdb_util, kpropd) which replace the entire
|
||||
* database in one fell swoop.
|
||||
*
|
||||
* The first locking protocol is implemented using flock() in the
|
||||
* krb_dbl_lock() and krb_dbl_unlock routines.
|
||||
*
|
||||
* The second locking protocol is necessary because DBM "files" are
|
||||
* actually implemented as two separate files, and it is impossible to
|
||||
* atomically rename two files simultaneously. It assumes that the
|
||||
* database is replaced only very infrequently in comparison to the time
|
||||
* needed to do a database read operation.
|
||||
*
|
||||
* A third file is used as a "version" semaphore; the modification
|
||||
* time of this file is the "version number" of the database.
|
||||
* At the start of a read operation, the reader checks the version
|
||||
* number; at the end of the read operation, it checks again. If the
|
||||
* version number changed, or if the semaphore was nonexistant at
|
||||
* either time, the reader sleeps for a second to let things
|
||||
* stabilize, and then tries again; if it does not succeed after
|
||||
* KERB_DB_MAX_RETRY attempts, it gives up.
|
||||
*
|
||||
* On update, the semaphore file is deleted (if it exists) before any
|
||||
* update takes place; at the end of the update, it is replaced, with
|
||||
* a version number strictly greater than the version number which
|
||||
* existed at the start of the update.
|
||||
*
|
||||
* If the system crashes in the middle of an update, the semaphore
|
||||
* file is not automatically created on reboot; this is a feature, not
|
||||
* a bug, since the database may be inconsistant. Note that the
|
||||
* absence of a semaphore file does not prevent another _update_ from
|
||||
* taking place later. Database replacements take place automatically
|
||||
* only on slave servers; a crash in the middle of an update will be
|
||||
* fixed by the next slave propagation. A crash in the middle of an
|
||||
* update on the master would be somewhat more serious, but this would
|
||||
* likely be noticed by an administrator, who could fix the problem and
|
||||
* retry the operation.
|
||||
*/
|
||||
|
||||
/* Macros to convert ndbm names to dbm names.
|
||||
* Note that dbm_nextkey() cannot be simply converted using a macro, since
|
||||
* it is invoked giving the database, and nextkey() needs the previous key.
|
||||
*
|
||||
* Instead, all routines call "dbm_next" instead.
|
||||
*/
|
||||
|
||||
#ifndef NDBM
|
||||
typedef char DBM;
|
||||
|
||||
#define dbm_open(file, flags, mode) ((dbminit(file) == 0)?"":((char *)0))
|
||||
#define dbm_fetch(db, key) fetch(key)
|
||||
#define dbm_store(db, key, content, flag) store(key, content)
|
||||
#define dbm_firstkey(db) firstkey()
|
||||
#define dbm_next(db,key) nextkey(key)
|
||||
#define dbm_close(db) dbmclose()
|
||||
#else
|
||||
#define dbm_next(db,key) dbm_nextkey(db)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Utility routine: generate name of database file.
|
||||
*/
|
||||
|
||||
static char *gen_dbsuffix(db_name, sfx)
|
||||
char *db_name;
|
||||
char *sfx;
|
||||
{
|
||||
char *dbsuffix;
|
||||
|
||||
if (sfx == NULL)
|
||||
sfx = ".ok";
|
||||
|
||||
dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1);
|
||||
strcpy(dbsuffix, db_name);
|
||||
strcat(dbsuffix, sfx);
|
||||
return dbsuffix;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialization for data base routines.
|
||||
*/
|
||||
|
||||
kerb_db_init()
|
||||
{
|
||||
init = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* gracefully shut down database--must be called by ANY program that does
|
||||
* a kerb_db_init
|
||||
*/
|
||||
|
||||
kerb_db_fini()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the "name" of the current database to some alternate value.
|
||||
*
|
||||
* Passing a null pointer as "name" will set back to the default.
|
||||
* If the alternate database doesn't exist, nothing is changed.
|
||||
*/
|
||||
|
||||
kerb_db_set_name(name)
|
||||
char *name;
|
||||
{
|
||||
DBM *db;
|
||||
|
||||
if (name == NULL)
|
||||
name = default_db_name;
|
||||
db = dbm_open(name, 0, 0);
|
||||
if (db == NULL)
|
||||
return errno;
|
||||
dbm_close(db);
|
||||
kerb_dbl_fini();
|
||||
current_db_name = name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the last modification time of the database.
|
||||
*/
|
||||
|
||||
long kerb_get_db_age()
|
||||
{
|
||||
struct stat st;
|
||||
char *okname;
|
||||
long age;
|
||||
|
||||
okname = gen_dbsuffix(current_db_name, ".ok");
|
||||
|
||||
if (stat (okname, &st) < 0)
|
||||
age = 0;
|
||||
else
|
||||
age = st.st_mtime;
|
||||
|
||||
free (okname);
|
||||
return age;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the semaphore file; indicates that database is currently
|
||||
* under renovation.
|
||||
*
|
||||
* This is only for use when moving the database out from underneath
|
||||
* the server (for example, during slave updates).
|
||||
*/
|
||||
|
||||
static long kerb_start_update(db_name)
|
||||
char *db_name;
|
||||
{
|
||||
char *okname = gen_dbsuffix(db_name, ".ok");
|
||||
long age = kerb_get_db_age();
|
||||
|
||||
if (unlink(okname) < 0
|
||||
&& errno != ENOENT) {
|
||||
age = -1;
|
||||
}
|
||||
free (okname);
|
||||
return age;
|
||||
}
|
||||
|
||||
static long kerb_end_update(db_name, age)
|
||||
char *db_name;
|
||||
long age;
|
||||
{
|
||||
int fd;
|
||||
int retval = 0;
|
||||
char *new_okname = gen_dbsuffix(db_name, ".ok#");
|
||||
char *okname = gen_dbsuffix(db_name, ".ok");
|
||||
|
||||
fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
|
||||
if (fd < 0)
|
||||
retval = errno;
|
||||
else {
|
||||
struct stat st;
|
||||
struct timeval tv[2];
|
||||
/* make sure that semaphore is "after" previous value. */
|
||||
if (fstat (fd, &st) == 0
|
||||
&& st.st_mtime <= age) {
|
||||
tv[0].tv_sec = st.st_atime;
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = age;
|
||||
tv[1].tv_usec = 0;
|
||||
/* set times.. */
|
||||
utimes (new_okname, tv);
|
||||
fsync(fd);
|
||||
}
|
||||
close(fd);
|
||||
if (rename (new_okname, okname) < 0)
|
||||
retval = errno;
|
||||
}
|
||||
|
||||
free (new_okname);
|
||||
free (okname);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static long kerb_start_read()
|
||||
{
|
||||
return kerb_get_db_age();
|
||||
}
|
||||
|
||||
static long kerb_end_read(age)
|
||||
u_long age;
|
||||
{
|
||||
if (kerb_get_db_age() != age || age == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the database, assuming it's not there.
|
||||
*/
|
||||
|
||||
kerb_db_create(db_name)
|
||||
char *db_name;
|
||||
{
|
||||
char *okname = gen_dbsuffix(db_name, ".ok");
|
||||
int fd;
|
||||
register int ret = 0;
|
||||
#ifdef NDBM
|
||||
DBM *db;
|
||||
|
||||
db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
||||
if (db == NULL)
|
||||
ret = errno;
|
||||
else
|
||||
dbm_close(db);
|
||||
#else
|
||||
char *dirname = gen_dbsuffix(db_name, ".dir");
|
||||
char *pagname = gen_dbsuffix(db_name, ".pag");
|
||||
|
||||
fd = open(dirname, O_RDWR|O_CREAT|O_EXCL, 0600);
|
||||
if (fd < 0)
|
||||
ret = errno;
|
||||
else {
|
||||
close(fd);
|
||||
fd = open (pagname, O_RDWR|O_CREAT|O_EXCL, 0600);
|
||||
if (fd < 0)
|
||||
ret = errno;
|
||||
else
|
||||
close(fd);
|
||||
}
|
||||
if (dbminit(db_name) < 0)
|
||||
ret = errno;
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
|
||||
if (fd < 0)
|
||||
ret = errno;
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* "Atomically" rename the database in a way that locks out read
|
||||
* access in the middle of the rename.
|
||||
*
|
||||
* Not perfect; if we crash in the middle of an update, we don't
|
||||
* necessarily know to complete the transaction the rename, but...
|
||||
*/
|
||||
|
||||
kerb_db_rename(from, to)
|
||||
char *from;
|
||||
char *to;
|
||||
{
|
||||
#ifndef __FreeBSD__
|
||||
char *fromdir = gen_dbsuffix (from, ".dir");
|
||||
char *todir = gen_dbsuffix (to, ".dir");
|
||||
char *frompag = gen_dbsuffix (from , ".pag");
|
||||
char *topag = gen_dbsuffix (to, ".pag");
|
||||
#else
|
||||
char *fromdb = gen_dbsuffix (from, ".db");
|
||||
char *todb = gen_dbsuffix (to, ".db");
|
||||
#endif
|
||||
char *fromok = gen_dbsuffix(from, ".ok");
|
||||
long trans = kerb_start_update(to);
|
||||
int ok;
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
if ((rename (fromdir, todir) == 0)
|
||||
&& (rename (frompag, topag) == 0)) {
|
||||
#else
|
||||
if (rename (fromdb, todb) == 0) {
|
||||
#endif
|
||||
(void) unlink (fromok);
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
free (fromok);
|
||||
#ifndef __FreeBSD__
|
||||
free (fromdir);
|
||||
free (todir);
|
||||
free (frompag);
|
||||
free (topag);
|
||||
#else
|
||||
free(fromdb);
|
||||
free(todb);
|
||||
#endif
|
||||
if (ok)
|
||||
return kerb_end_update(to, trans);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* look up a principal in the data base returns number of principals
|
||||
* found , and whether there were more than requested.
|
||||
*/
|
||||
|
||||
kerb_db_get_principal(name, inst, principal, max, more)
|
||||
char *name; /* could have wild card */
|
||||
char *inst; /* could have wild card */
|
||||
Principal *principal;
|
||||
unsigned int max; /* max number of name structs to return */
|
||||
int *more; /* where there more than 'max' tuples? */
|
||||
|
||||
{
|
||||
int found = 0, code;
|
||||
extern int errorproc();
|
||||
int wildp, wildi;
|
||||
datum key, contents;
|
||||
char testname[ANAME_SZ], testinst[INST_SZ];
|
||||
u_long trans;
|
||||
int try;
|
||||
DBM *db;
|
||||
|
||||
if (!init)
|
||||
kerb_db_init(); /* initialize database routines */
|
||||
|
||||
for (try = 0; try < KERB_DB_MAX_RETRY; try++) {
|
||||
trans = kerb_start_read();
|
||||
|
||||
if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
|
||||
return -1;
|
||||
|
||||
db = dbm_open(current_db_name, O_RDONLY, 0600);
|
||||
|
||||
*more = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2)
|
||||
fprintf(stderr,
|
||||
"%s: db_get_principal for %s %s max = %d",
|
||||
progname, name, inst, max);
|
||||
#endif
|
||||
|
||||
wildp = !strcmp(name, "*");
|
||||
wildi = !strcmp(inst, "*");
|
||||
|
||||
if (!wildi && !wildp) { /* nothing's wild */
|
||||
encode_princ_key(&key, name, inst);
|
||||
contents = dbm_fetch(db, key);
|
||||
if (contents.dptr == NULL) {
|
||||
found = 0;
|
||||
goto done;
|
||||
}
|
||||
decode_princ_contents(&contents, principal);
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1) {
|
||||
fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n",
|
||||
principal->name, principal->instance,
|
||||
strlen(principal->name),
|
||||
strlen(principal->instance));
|
||||
}
|
||||
#endif
|
||||
found = 1;
|
||||
goto done;
|
||||
}
|
||||
/* process wild cards by looping through entire database */
|
||||
|
||||
for (key = dbm_firstkey(db); key.dptr != NULL;
|
||||
key = dbm_next(db, key)) {
|
||||
decode_princ_key(&key, testname, testinst);
|
||||
if ((wildp || !strcmp(testname, name)) &&
|
||||
(wildi || !strcmp(testinst, inst))) { /* have a match */
|
||||
if (found >= max) {
|
||||
*more = 1;
|
||||
goto done;
|
||||
} else {
|
||||
found++;
|
||||
contents = dbm_fetch(db, key);
|
||||
decode_princ_contents(&contents, principal);
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1) {
|
||||
fprintf(stderr,
|
||||
"\tfound %s %s p_n length %d t_n length %d\n",
|
||||
principal->name, principal->instance,
|
||||
strlen(principal->name),
|
||||
strlen(principal->instance));
|
||||
}
|
||||
#endif
|
||||
principal++; /* point to next */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
kerb_dbl_unlock(); /* unlock read lock */
|
||||
dbm_close(db);
|
||||
if (kerb_end_read(trans) == 0)
|
||||
break;
|
||||
found = -1;
|
||||
if (!non_blocking)
|
||||
sleep(1);
|
||||
}
|
||||
return (found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a name in the data base. Returns number of names
|
||||
* successfully updated.
|
||||
*/
|
||||
|
||||
kerb_db_put_principal(principal, max)
|
||||
Principal *principal;
|
||||
unsigned int max; /* number of principal structs to
|
||||
* update */
|
||||
|
||||
{
|
||||
int found = 0, code;
|
||||
u_long i;
|
||||
extern int errorproc();
|
||||
datum key, contents;
|
||||
DBM *db;
|
||||
|
||||
gettimeofday(×tamp, NULL);
|
||||
|
||||
if (!init)
|
||||
kerb_db_init();
|
||||
|
||||
if ((code = kerb_dbl_lock(KERB_DBL_EXCLUSIVE)) != 0)
|
||||
return -1;
|
||||
|
||||
db = dbm_open(current_db_name, O_RDWR, 0600);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 2)
|
||||
fprintf(stderr, "%s: kerb_db_put_principal max = %d",
|
||||
progname, max);
|
||||
#endif
|
||||
|
||||
/* for each one, stuff temps, and do replace/append */
|
||||
for (i = 0; i < max; i++) {
|
||||
encode_princ_contents(&contents, principal);
|
||||
encode_princ_key(&key, principal->name, principal->instance);
|
||||
dbm_store(db, key, contents, DBM_REPLACE);
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1) {
|
||||
fprintf(stderr, "\n put %s %s\n",
|
||||
principal->name, principal->instance);
|
||||
}
|
||||
#endif
|
||||
found++;
|
||||
principal++; /* bump to next struct */
|
||||
}
|
||||
|
||||
dbm_close(db);
|
||||
kerb_dbl_unlock(); /* unlock database */
|
||||
return (found);
|
||||
}
|
||||
|
||||
static void
|
||||
encode_princ_key(key, name, instance)
|
||||
datum *key;
|
||||
char *name, *instance;
|
||||
{
|
||||
static char keystring[ANAME_SZ + INST_SZ];
|
||||
|
||||
bzero(keystring, ANAME_SZ + INST_SZ);
|
||||
strncpy(keystring, name, ANAME_SZ);
|
||||
strncpy(&keystring[ANAME_SZ], instance, INST_SZ);
|
||||
key->dptr = keystring;
|
||||
key->dsize = ANAME_SZ + INST_SZ;
|
||||
}
|
||||
|
||||
static void
|
||||
decode_princ_key(key, name, instance)
|
||||
datum *key;
|
||||
char *name, *instance;
|
||||
{
|
||||
strncpy(name, key->dptr, ANAME_SZ);
|
||||
strncpy(instance, key->dptr + ANAME_SZ, INST_SZ);
|
||||
name[ANAME_SZ - 1] = '\0';
|
||||
instance[INST_SZ - 1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
encode_princ_contents(contents, principal)
|
||||
datum *contents;
|
||||
Principal *principal;
|
||||
{
|
||||
contents->dsize = sizeof(*principal);
|
||||
contents->dptr = (char *) principal;
|
||||
}
|
||||
|
||||
static void
|
||||
decode_princ_contents(contents, principal)
|
||||
datum *contents;
|
||||
Principal *principal;
|
||||
{
|
||||
bcopy(contents->dptr, (char *) principal, sizeof(*principal));
|
||||
}
|
||||
|
||||
kerb_db_get_stat(s)
|
||||
DB_stat *s;
|
||||
{
|
||||
gettimeofday(×tamp, NULL);
|
||||
|
||||
|
||||
s->cpu = 0;
|
||||
s->elapsed = 0;
|
||||
s->dio = 0;
|
||||
s->pfault = 0;
|
||||
s->t_stamp = timestamp.tv_sec;
|
||||
s->n_retrieve = 0;
|
||||
s->n_replace = 0;
|
||||
s->n_append = 0;
|
||||
s->n_get_stat = 0;
|
||||
s->n_put_stat = 0;
|
||||
/* update local copy too */
|
||||
}
|
||||
|
||||
kerb_db_put_stat(s)
|
||||
DB_stat *s;
|
||||
{
|
||||
}
|
||||
|
||||
delta_stat(a, b, c)
|
||||
DB_stat *a, *b, *c;
|
||||
{
|
||||
/* c = a - b then b = a for the next time */
|
||||
|
||||
c->cpu = a->cpu - b->cpu;
|
||||
c->elapsed = a->elapsed - b->elapsed;
|
||||
c->dio = a->dio - b->dio;
|
||||
c->pfault = a->pfault - b->pfault;
|
||||
c->t_stamp = a->t_stamp - b->t_stamp;
|
||||
c->n_retrieve = a->n_retrieve - b->n_retrieve;
|
||||
c->n_replace = a->n_replace - b->n_replace;
|
||||
c->n_append = a->n_append - b->n_append;
|
||||
c->n_get_stat = a->n_get_stat - b->n_get_stat;
|
||||
c->n_put_stat = a->n_put_stat - b->n_put_stat;
|
||||
|
||||
bcopy(a, b, sizeof(DB_stat));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* look up a dba in the data base returns number of dbas found , and
|
||||
* whether there were more than requested.
|
||||
*/
|
||||
|
||||
kerb_db_get_dba(dba_name, dba_inst, dba, max, more)
|
||||
char *dba_name; /* could have wild card */
|
||||
char *dba_inst; /* could have wild card */
|
||||
Dba *dba;
|
||||
unsigned int max; /* max number of name structs to return */
|
||||
int *more; /* where there more than 'max' tuples? */
|
||||
|
||||
{
|
||||
*more = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
kerb_db_iterate (func, arg)
|
||||
int (*func)();
|
||||
char *arg; /* void *, really */
|
||||
{
|
||||
datum key, contents;
|
||||
Principal *principal;
|
||||
int code;
|
||||
DBM *db;
|
||||
|
||||
kerb_db_init(); /* initialize and open the database */
|
||||
if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
|
||||
return code;
|
||||
|
||||
db = dbm_open(current_db_name, O_RDONLY, 0600);
|
||||
|
||||
for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) {
|
||||
contents = dbm_fetch (db, key);
|
||||
/* XXX may not be properly aligned */
|
||||
principal = (Principal *) contents.dptr;
|
||||
if ((code = (*func)(arg, principal)) != 0)
|
||||
return code;
|
||||
}
|
||||
dbm_close(db);
|
||||
kerb_dbl_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dblfd = -1;
|
||||
static int mylock = 0;
|
||||
static int inited = 0;
|
||||
|
||||
static kerb_dbl_init()
|
||||
{
|
||||
if (!inited) {
|
||||
char *filename = gen_dbsuffix (current_db_name, ".ok");
|
||||
if ((dblfd = open(filename, 0)) < 0) {
|
||||
fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename);
|
||||
fflush(stderr);
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
free(filename);
|
||||
inited++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void kerb_dbl_fini()
|
||||
{
|
||||
close(dblfd);
|
||||
dblfd = -1;
|
||||
inited = 0;
|
||||
mylock = 0;
|
||||
}
|
||||
|
||||
static int kerb_dbl_lock(mode)
|
||||
int mode;
|
||||
{
|
||||
int flock_mode;
|
||||
|
||||
if (!inited)
|
||||
kerb_dbl_init();
|
||||
if (mylock) { /* Detect lock call when lock already
|
||||
* locked */
|
||||
fprintf(stderr, "Kerberos locking error (mylock)\n");
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
switch (mode) {
|
||||
case KERB_DBL_EXCLUSIVE:
|
||||
flock_mode = LOCK_EX;
|
||||
break;
|
||||
case KERB_DBL_SHARED:
|
||||
flock_mode = LOCK_SH;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "invalid lock mode %d\n", mode);
|
||||
abort();
|
||||
}
|
||||
if (non_blocking)
|
||||
flock_mode |= LOCK_NB;
|
||||
|
||||
if (flock(dblfd, flock_mode) < 0)
|
||||
return errno;
|
||||
mylock++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kerb_dbl_unlock()
|
||||
{
|
||||
if (!mylock) { /* lock already unlocked */
|
||||
fprintf(stderr, "Kerberos database lock not locked when unlocking.\n");
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (flock(dblfd, LOCK_UN) < 0) {
|
||||
fprintf(stderr, "Kerberos database lock error. (unlocking)\n");
|
||||
fflush(stderr);
|
||||
perror("flock");
|
||||
exit(1);
|
||||
}
|
||||
mylock = 0;
|
||||
}
|
||||
|
||||
int kerb_db_set_lockmode(mode)
|
||||
int mode;
|
||||
{
|
||||
int old = non_blocking;
|
||||
non_blocking = mode;
|
||||
return old;
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* Utility routines for Kerberos programs which directly access
|
||||
* the database. This code was duplicated in too many places
|
||||
* before I gathered it here.
|
||||
*
|
||||
* Jon Rochlis, MIT Telecom, March 1988
|
||||
*
|
||||
* from: krb_kdb_utils.c,v 4.1 89/07/26 11:01:12 jtkohl Exp $
|
||||
* $Id: krb_kdb_utils.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: krb_kdb_utils.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <krb_db.h>
|
||||
#include <kdc.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
long kdb_get_master_key(prompt, master_key, master_key_sched)
|
||||
int prompt;
|
||||
C_Block master_key;
|
||||
Key_schedule master_key_sched;
|
||||
{
|
||||
int kfile;
|
||||
|
||||
if (prompt) {
|
||||
#ifdef NOENCRYPTION
|
||||
placebo_read_password(master_key,
|
||||
"\nEnter Kerberos master key: ", 0);
|
||||
#else
|
||||
des_read_password(master_key,
|
||||
"\nEnter Kerberos master key: ", 0);
|
||||
#endif
|
||||
printf ("\n");
|
||||
}
|
||||
else {
|
||||
kfile = open(MKEYFILE, O_RDONLY, 0600);
|
||||
if (kfile < 0) {
|
||||
/* oh, for com_err_ */
|
||||
return (-1);
|
||||
}
|
||||
if (read(kfile, (char *) master_key, 8) != 8) {
|
||||
return (-1);
|
||||
}
|
||||
close(kfile);
|
||||
}
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(master_key,master_key_sched);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* The caller is reasponsible for cleaning up the master key and sched,
|
||||
even if we can't verify the master key */
|
||||
|
||||
/* Returns master key version if successful, otherwise -1 */
|
||||
|
||||
long kdb_verify_master_key (master_key, master_key_sched, out)
|
||||
C_Block master_key;
|
||||
Key_schedule master_key_sched;
|
||||
FILE *out; /* setting this to non-null be do output */
|
||||
{
|
||||
C_Block key_from_db;
|
||||
Principal principal_data[1];
|
||||
int n, more = 0;
|
||||
long master_key_version;
|
||||
|
||||
/* lookup the master key version */
|
||||
n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
|
||||
1 /* only one please */, &more);
|
||||
if ((n != 1) || more) {
|
||||
if (out != (FILE *) NULL)
|
||||
fprintf(out,
|
||||
"verify_master_key: %s, %d found.\n",
|
||||
"Kerberos error on master key version lookup",
|
||||
n);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
master_key_version = (long) principal_data[0].key_version;
|
||||
|
||||
/* set up the master key */
|
||||
if (out != (FILE *) NULL) /* should we punt this? */
|
||||
fprintf(out, "Current Kerberos master key version is %d.\n",
|
||||
principal_data[0].kdc_key_ver);
|
||||
|
||||
/*
|
||||
* now use the master key to decrypt the key in the db, had better
|
||||
* be the same!
|
||||
*/
|
||||
bcopy(&principal_data[0].key_low, key_from_db, 4);
|
||||
bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4);
|
||||
kdb_encrypt_key (key_from_db, key_from_db,
|
||||
master_key, master_key_sched, DECRYPT);
|
||||
|
||||
/* the decrypted database key had better equal the master key */
|
||||
n = bcmp((char *) master_key, (char *) key_from_db,
|
||||
sizeof(master_key));
|
||||
/* this used to zero the master key here! */
|
||||
bzero(key_from_db, sizeof(key_from_db));
|
||||
bzero(principal_data, sizeof (principal_data));
|
||||
|
||||
if (n && (out != (FILE *) NULL)) {
|
||||
fprintf(out, "\n\07\07verify_master_key: Invalid master key; ");
|
||||
fprintf(out, "does not match database.\n");
|
||||
return (-1);
|
||||
}
|
||||
if (out != (FILE *) NULL) {
|
||||
fprintf(out, "\nMaster key entered. BEWARE!\07\07\n");
|
||||
fflush(out);
|
||||
}
|
||||
|
||||
return (master_key_version);
|
||||
}
|
||||
|
||||
/* The old algorithm used the key schedule as the initial vector which
|
||||
was byte order depedent ... */
|
||||
|
||||
kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag)
|
||||
C_Block in, out, master_key;
|
||||
Key_schedule master_key_sched;
|
||||
int e_d_flag;
|
||||
{
|
||||
|
||||
#ifdef NOENCRYPTION
|
||||
bcopy(in, out, sizeof(C_Block));
|
||||
#else
|
||||
pcbc_encrypt(in,out,(long)sizeof(C_Block),master_key_sched,master_key,
|
||||
e_d_flag);
|
||||
#endif
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* $Source: /home/ncvs/src/eBones/kdb/krb_lib.c,v $
|
||||
* $Author: csgr $
|
||||
*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <mit-copyright.h>.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: krb_lib.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <strings.h>
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <krb_db.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int debug;
|
||||
extern char *progname;
|
||||
long kerb_debug;
|
||||
#endif
|
||||
|
||||
extern char *strncpy();
|
||||
extern char *ctime();
|
||||
extern char *getenv();
|
||||
|
||||
static init = 0;
|
||||
|
||||
/*
|
||||
* initialization routine for data base
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_init()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!init) {
|
||||
char *dbg = getenv("KERB_DBG");
|
||||
if (dbg)
|
||||
sscanf(dbg, "%d", &kerb_debug);
|
||||
init = 1;
|
||||
}
|
||||
#endif
|
||||
kerb_db_init();
|
||||
|
||||
#ifdef CACHE
|
||||
kerb_cache_init();
|
||||
#endif
|
||||
|
||||
/* successful init, return 0, else errcode */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* finalization routine for database -- NOTE: MUST be called by any
|
||||
* program using kerb_init. ALSO will have to be modified to finalize
|
||||
* caches, if they're ever really implemented.
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_fini()
|
||||
{
|
||||
kerb_db_fini();
|
||||
}
|
||||
|
||||
/*
|
||||
* look up a principal in the cache or data base returns number of
|
||||
* principals found
|
||||
*/
|
||||
|
||||
int
|
||||
kerb_get_principal(name, inst, principal, max, more)
|
||||
char *name; /* could have wild card */
|
||||
char *inst; /* could have wild card */
|
||||
Principal *principal;
|
||||
unsigned int max; /* max number of name structs to return */
|
||||
int *more; /* more tuples than room for */
|
||||
|
||||
{
|
||||
int found = 0;
|
||||
#ifdef CACHE
|
||||
static int wild = 0;
|
||||
#endif
|
||||
if (!init)
|
||||
kerb_init();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1)
|
||||
fprintf(stderr, "\n%s: kerb_get_principal for %s %s max = %d\n",
|
||||
progname, name, inst, max);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* if this is a request including a wild card, have to go to db
|
||||
* since the cache may not be exhaustive.
|
||||
*/
|
||||
|
||||
/* clear the principal area */
|
||||
bzero((char *) principal, max * sizeof(Principal));
|
||||
|
||||
#ifdef CACHE
|
||||
/*
|
||||
* so check to see if the name contains a wildcard "*" or "?", not
|
||||
* preceeded by a backslash.
|
||||
*/
|
||||
wild = 0;
|
||||
if (index(name, '*') || index(name, '?') ||
|
||||
index(inst, '*') || index(inst, '?'))
|
||||
wild = 1;
|
||||
|
||||
if (!wild) {
|
||||
/* try the cache first */
|
||||
found = kerb_cache_get_principal(name, inst, principal, max, more);
|
||||
if (found)
|
||||
return (found);
|
||||
}
|
||||
#endif
|
||||
/* If we didn't try cache, or it wasn't there, try db */
|
||||
found = kerb_db_get_principal(name, inst, principal, max, more);
|
||||
/* try to insert principal(s) into cache if it was found */
|
||||
#ifdef CACHE
|
||||
if (found) {
|
||||
kerb_cache_put_principal(principal, found);
|
||||
}
|
||||
#endif
|
||||
return (found);
|
||||
}
|
||||
|
||||
/* principals */
|
||||
kerb_put_principal(principal, n)
|
||||
Principal *principal;
|
||||
unsigned int n; /* number of principal structs to write */
|
||||
{
|
||||
long time();
|
||||
struct tm *tp, *localtime();
|
||||
|
||||
/* set mod date */
|
||||
principal->mod_date = time((long *)0);
|
||||
/* and mod date string */
|
||||
|
||||
tp = localtime(&principal->mod_date);
|
||||
(void) sprintf(principal->mod_date_txt, "%4d-%2d-%2d",
|
||||
tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
|
||||
tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1) {
|
||||
int i;
|
||||
fprintf(stderr, "\nkerb_put_principal...");
|
||||
for (i = 0; i < n; i++) {
|
||||
krb_print_principal(&principal[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* write database */
|
||||
if (kerb_db_put_principal(principal, n) < 0) {
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1)
|
||||
fprintf(stderr, "\n%s: kerb_db_put_principal err", progname);
|
||||
/* watch out for cache */
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#ifdef CACHE
|
||||
/* write cache */
|
||||
if (!kerb_cache_put_principal(principal, n)) {
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1)
|
||||
fprintf(stderr, "\n%s: kerb_cache_put_principal err", progname);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kerb_get_dba(name, inst, dba, max, more)
|
||||
char *name; /* could have wild card */
|
||||
char *inst; /* could have wild card */
|
||||
Dba *dba;
|
||||
unsigned int max; /* max number of name structs to return */
|
||||
int *more; /* more tuples than room for */
|
||||
|
||||
{
|
||||
int found = 0;
|
||||
#ifdef CACHE
|
||||
static int wild = 0;
|
||||
#endif
|
||||
if (!init)
|
||||
kerb_init();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kerb_debug & 1)
|
||||
fprintf(stderr, "\n%s: kerb_get_dba for %s %s max = %d\n",
|
||||
progname, name, inst, max);
|
||||
#endif
|
||||
/*
|
||||
* if this is a request including a wild card, have to go to db
|
||||
* since the cache may not be exhaustive.
|
||||
*/
|
||||
|
||||
/* clear the dba area */
|
||||
bzero((char *) dba, max * sizeof(Dba));
|
||||
|
||||
#ifdef CACHE
|
||||
/*
|
||||
* so check to see if the name contains a wildcard "*" or "?", not
|
||||
* preceeded by a backslash.
|
||||
*/
|
||||
|
||||
wild = 0;
|
||||
if (index(name, '*') || index(name, '?') ||
|
||||
index(inst, '*') || index(inst, '?'))
|
||||
wild = 1;
|
||||
|
||||
if (!wild) {
|
||||
/* try the cache first */
|
||||
found = kerb_cache_get_dba(name, inst, dba, max, more);
|
||||
if (found)
|
||||
return (found);
|
||||
}
|
||||
#endif
|
||||
/* If we didn't try cache, or it wasn't there, try db */
|
||||
found = kerb_db_get_dba(name, inst, dba, max, more);
|
||||
#ifdef CACHE
|
||||
/* try to insert dba(s) into cache if it was found */
|
||||
if (found) {
|
||||
kerb_cache_put_dba(dba, found);
|
||||
}
|
||||
#endif
|
||||
return (found);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: $Header: /home/ncvs/src/eBones/kdb/print_princ.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $
|
||||
* $Id: print_princ.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: print_princ.c,v 1.1.1.1 1994/09/30 14:49:55 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <strings.h>
|
||||
#include <krb.h>
|
||||
#include <krb_db.h>
|
||||
|
||||
extern int debug;
|
||||
extern char *strncpy();
|
||||
extern char *ctime();
|
||||
extern struct tm *localtime();
|
||||
struct tm *time_p;
|
||||
|
||||
long kerb_debug;
|
||||
|
||||
krb_print_principal(a_n)
|
||||
Principal *a_n;
|
||||
{
|
||||
/* run-time database does not contain string versions */
|
||||
time_p = localtime(&(a_n->exp_date));
|
||||
|
||||
fprintf(stderr,
|
||||
"\n%s %s expires %4d-%2d-%2d %2d:%2d, max_life %d*5 = %d min attr 0x%02x",
|
||||
a_n->name, a_n->instance,
|
||||
time_p->tm_year > 1900 ? time_p->tm_year : time_p->tm_year + 1900,
|
||||
time_p->tm_mon + 1, time_p->tm_mday,
|
||||
time_p->tm_hour, time_p->tm_min,
|
||||
a_n->max_life, 5 * a_n->max_life, a_n->attributes);
|
||||
|
||||
fprintf(stderr,
|
||||
"\n\tkey_ver %d k_low 0x%08x k_high 0x%08x akv %d exists %d\n",
|
||||
a_n->key_version, a_n->key_low, a_n->key_high,
|
||||
a_n->kdc_key_ver, a_n->old);
|
||||
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
|
||||
# $Id: Makefile,v 1.4 1995/01/20 01:12:19 wollman Exp $
|
||||
|
||||
LIB= krb
|
||||
SHLIB_MAJOR= 2
|
||||
SHLIB_MINOR= 0
|
||||
CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${.CURDIR}/../include -DBSD42
|
||||
SRCS= krb_err.c create_auth_reply.c create_ciph.c \
|
||||
create_death_packet.c create_ticket.c debug_decl.c decomp_ticket.c \
|
||||
des_rw.c dest_tkt.c extract_ticket.c fgetst.c get_ad_tkt.c \
|
||||
get_admhst.c get_cred.c get_in_tkt.c get_krbhst.c get_krbrlm.c \
|
||||
get_phost.c get_pw_tkt.c get_request.c get_svc_in_tkt.c \
|
||||
get_tf_fullname.c get_tf_realm.c getrealm.c getst.c in_tkt.c \
|
||||
k_gethostname.c klog.c kname_parse.c kntoln.c kparse.c \
|
||||
krb_err_txt.c krb_get_in_tkt.c kuserok.c log.c mk_err.c \
|
||||
mk_priv.c mk_req.c mk_safe.c month_sname.c \
|
||||
netread.c netwrite.c one.c pkt_cipher.c pkt_clen.c rd_err.c \
|
||||
rd_priv.c rd_req.c rd_safe.c read_service_key.c recvauth.c \
|
||||
save_credentials.c send_to_kdc.c sendauth.c stime.c tf_util.c \
|
||||
tkt_string.c util.c
|
||||
|
||||
TDIR= ${.CURDIR}/..
|
||||
krb_err.c krb_err.h: krb_err.et
|
||||
test -e krb_err.et || ln -s ${.CURDIR}/krb_err.et .
|
||||
${COMPILE_ET} krb_err.et
|
||||
LDADD+= -lcom_err
|
||||
|
||||
beforeinstall:
|
||||
-cd ${.OBJDIR}; cmp -s krb_err.h \
|
||||
${DESTDIR}/usr/include/kerberosIV/krb_err.h || \
|
||||
install -c -o ${BINOWN} -g ${BINGRP} -m 444 krb_err.h \
|
||||
${DESTDIR}/usr/include/kerberosIV
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: add_ticket.c,v 4.7 88/10/07 06:06:26 shanzer Exp $
|
||||
* $Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: add_ticket.c,v 1.2 1994/07/19 19:24:54 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This routine is now obsolete. It used to be possible to request
|
||||
* more than one ticket at a time from the authentication server, and
|
||||
* it looks like this routine was used by the server to package the
|
||||
* tickets to be returned to the client.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine adds a new ticket to the ciphertext to be returned to
|
||||
* the client. The routine takes the ciphertext (which doesn't get
|
||||
* encrypted till later), the number of the ticket (i.e. 1st, 2nd,
|
||||
* etc) the session key which goes in the ticket and is sent back to
|
||||
* the user, the lifetime for the ticket, the service name, the
|
||||
* instance, the realm, the key version number, and the ticket itself.
|
||||
*
|
||||
* This routine returns 0 (KSUCCESS) on success, and 1 (KFAILURE) on
|
||||
* failure. On failure, which occurs when there isn't enough room
|
||||
* for the ticket, a 0 length ticket is added.
|
||||
*
|
||||
* Notes: This routine must be called with successive values of n.
|
||||
* i.e. the ticket must be added in order. The corresponding routine
|
||||
* on the client side is extract ticket.
|
||||
*/
|
||||
|
||||
/* XXX they aren't all used; to avoid incompatible changes we will
|
||||
* fool lint for the moment */
|
||||
/*ARGSUSED */
|
||||
add_ticket(cipher,n,session,lifetime,sname,instance,realm,kvno,ticket)
|
||||
KTEXT cipher; /* Ciphertext info for ticket */
|
||||
char *sname; /* Service name */
|
||||
char *instance; /* Instance */
|
||||
int n; /* Relative position of this ticket */
|
||||
char *session; /* Session key for this tkt */
|
||||
int lifetime; /* Lifetime of this ticket */
|
||||
char *realm; /* Realm in which ticket is valid */
|
||||
int kvno; /* Key version number of service key */
|
||||
KTEXT ticket; /* The ticket itself */
|
||||
{
|
||||
|
||||
/* Note, the 42 is a temporary hack; it will have to be changed. */
|
||||
|
||||
/* Begin check of ticket length */
|
||||
if ((cipher->length + ticket->length + 4 + 42 +
|
||||
(*(cipher->dat)+1-n)*(11+strlen(realm))) >
|
||||
MAX_KTXT_LEN) {
|
||||
bcopy(session,(char *)(cipher->dat+cipher->length),8);
|
||||
*(cipher->dat+cipher->length+8) = (char) lifetime;
|
||||
*(cipher->dat+cipher->length+9) = (char) kvno;
|
||||
(void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
|
||||
cipher->length += 11 + strlen(realm);
|
||||
*(cipher->dat+n) = 0;
|
||||
return(KFAILURE);
|
||||
}
|
||||
/* End check of ticket length */
|
||||
|
||||
/* Add the session key, lifetime, kvno, ticket to the ciphertext */
|
||||
bcopy(session,(char *)(cipher->dat+cipher->length),8);
|
||||
*(cipher->dat+cipher->length+8) = (char) lifetime;
|
||||
*(cipher->dat+cipher->length+9) = (char) kvno;
|
||||
(void) strcpy((char *)(cipher->dat+cipher->length+10),realm);
|
||||
cipher->length += 11 + strlen(realm);
|
||||
bcopy((char *)(ticket->dat),(char *)(cipher->dat+cipher->length),
|
||||
ticket->length);
|
||||
cipher->length += ticket->length;
|
||||
|
||||
/* Set the ticket length at beginning of ciphertext */
|
||||
*(cipher->dat+n) = ticket->length;
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: create_auth_reply.c,v 4.10 89/01/13 17:47:38 steiner Exp $
|
||||
* $Id: create_auth_reply.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: create_auth_reply.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This routine is called by the Kerberos authentication server
|
||||
* to create a reply to an authentication request. The routine
|
||||
* takes the user's name, instance, and realm, the client's
|
||||
* timestamp, the number of tickets, the user's key version
|
||||
* number and the ciphertext containing the tickets themselves.
|
||||
* It constructs a packet and returns a pointer to it.
|
||||
*
|
||||
* Notes: The packet returned by this routine is static. Thus, if you
|
||||
* intend to keep the result beyond the next call to this routine, you
|
||||
* must copy it elsewhere.
|
||||
*
|
||||
* The packet is built in the following format:
|
||||
*
|
||||
* variable
|
||||
* type or constant data
|
||||
* ---- ----------- ----
|
||||
*
|
||||
* unsigned char KRB_PROT_VERSION protocol version number
|
||||
*
|
||||
* unsigned char AUTH_MSG_KDC_REPLY protocol message type
|
||||
*
|
||||
* [least significant HOST_BYTE_ORDER sender's (server's) byte
|
||||
* bit of above field] order
|
||||
*
|
||||
* string pname principal's name
|
||||
*
|
||||
* string pinst principal's instance
|
||||
*
|
||||
* string prealm principal's realm
|
||||
*
|
||||
* unsigned long time_ws client's timestamp
|
||||
*
|
||||
* unsigned char n number of tickets
|
||||
*
|
||||
* unsigned long x_date expiration date
|
||||
*
|
||||
* unsigned char kvno master key version
|
||||
*
|
||||
* short w_1 cipher length
|
||||
*
|
||||
* --- cipher->dat cipher data
|
||||
*/
|
||||
|
||||
KTEXT
|
||||
create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
|
||||
char *pname; /* Principal's name */
|
||||
char *pinst; /* Principal's instance */
|
||||
char *prealm; /* Principal's authentication domain */
|
||||
long time_ws; /* Workstation time */
|
||||
int n; /* Number of tickets */
|
||||
unsigned long x_date; /* Principal's expiration date */
|
||||
int kvno; /* Principal's key version number */
|
||||
KTEXT cipher; /* Cipher text with tickets and
|
||||
* session keys */
|
||||
{
|
||||
static KTEXT_ST pkt_st;
|
||||
KTEXT pkt = &pkt_st;
|
||||
unsigned char *v = pkt->dat; /* Prot vers number */
|
||||
unsigned char *t = (pkt->dat+1); /* Prot message type */
|
||||
short w_l; /* Cipher length */
|
||||
|
||||
/* Create fixed part of packet */
|
||||
*v = (unsigned char) KRB_PROT_VERSION;
|
||||
*t = (unsigned char) AUTH_MSG_KDC_REPLY;
|
||||
*t |= HOST_BYTE_ORDER;
|
||||
|
||||
if (n != 0)
|
||||
*v = 3;
|
||||
|
||||
/* Add the basic info */
|
||||
(void) strcpy((char *) (pkt->dat+2), pname);
|
||||
pkt->length = 3 + strlen(pname);
|
||||
(void) strcpy((char *) (pkt->dat+pkt->length),pinst);
|
||||
pkt->length += 1 + strlen(pinst);
|
||||
(void) strcpy((char *) (pkt->dat+pkt->length),prealm);
|
||||
pkt->length += 1 + strlen(prealm);
|
||||
/* Workstation timestamp */
|
||||
bcopy((char *) &time_ws, (char *) (pkt->dat+pkt->length), 4);
|
||||
pkt->length += 4;
|
||||
*(pkt->dat+(pkt->length)++) = (unsigned char) n;
|
||||
/* Expiration date */
|
||||
bcopy((char *) &x_date, (char *) (pkt->dat+pkt->length),4);
|
||||
pkt->length += 4;
|
||||
|
||||
/* Now send the ciphertext and info to help decode it */
|
||||
*(pkt->dat+(pkt->length)++) = (unsigned char) kvno;
|
||||
w_l = (short) cipher->length;
|
||||
bcopy((char *) &w_l,(char *) (pkt->dat+pkt->length),2);
|
||||
pkt->length += 2;
|
||||
bcopy((char *) (cipher->dat), (char *) (pkt->dat+pkt->length),
|
||||
cipher->length);
|
||||
pkt->length += cipher->length;
|
||||
|
||||
/* And return the packet */
|
||||
return pkt;
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: create_ciph.c,v 4.8 89/05/18 21:24:26 jis Exp $
|
||||
* $Id: create_ciph.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: create_ciph.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <des.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This routine is used by the authentication server to create
|
||||
* a packet for its client, containing a ticket for the requested
|
||||
* service (given in "tkt"), and some information about the ticket,
|
||||
*
|
||||
* Returns KSUCCESS no matter what.
|
||||
*
|
||||
* The length of the cipher is stored in c->length; the format of
|
||||
* c->dat is as follows:
|
||||
*
|
||||
* variable
|
||||
* type or constant data
|
||||
* ---- ----------- ----
|
||||
*
|
||||
*
|
||||
* 8 bytes session session key for client, service
|
||||
*
|
||||
* string service service name
|
||||
*
|
||||
* string instance service instance
|
||||
*
|
||||
* string realm KDC realm
|
||||
*
|
||||
* unsigned char life ticket lifetime
|
||||
*
|
||||
* unsigned char kvno service key version number
|
||||
*
|
||||
* unsigned char tkt->length length of following ticket
|
||||
*
|
||||
* data tkt->dat ticket for service
|
||||
*
|
||||
* 4 bytes kdc_time KDC's timestamp
|
||||
*
|
||||
* <=7 bytes null null pad to 8 byte multiple
|
||||
*
|
||||
*/
|
||||
|
||||
create_ciph(c, session, service, instance, realm, life, kvno, tkt,
|
||||
kdc_time, key)
|
||||
KTEXT c; /* Text block to hold ciphertext */
|
||||
C_Block session; /* Session key to send to user */
|
||||
char *service; /* Service name on ticket */
|
||||
char *instance; /* Instance name on ticket */
|
||||
char *realm; /* Realm of this KDC */
|
||||
unsigned long life; /* Lifetime of the ticket */
|
||||
int kvno; /* Key version number for service */
|
||||
KTEXT tkt; /* The ticket for the service */
|
||||
unsigned long kdc_time; /* KDC time */
|
||||
C_Block key; /* Key to encrypt ciphertext with */
|
||||
{
|
||||
char *ptr;
|
||||
Key_schedule key_s;
|
||||
|
||||
ptr = (char *) c->dat;
|
||||
|
||||
bcopy((char *) session, ptr, 8);
|
||||
ptr += 8;
|
||||
|
||||
(void) strcpy(ptr,service);
|
||||
ptr += strlen(service) + 1;
|
||||
|
||||
(void) strcpy(ptr,instance);
|
||||
ptr += strlen(instance) + 1;
|
||||
|
||||
(void) strcpy(ptr,realm);
|
||||
ptr += strlen(realm) + 1;
|
||||
|
||||
*(ptr++) = (unsigned char) life;
|
||||
*(ptr++) = (unsigned char) kvno;
|
||||
*(ptr++) = (unsigned char) tkt->length;
|
||||
|
||||
bcopy((char *)(tkt->dat),ptr,tkt->length);
|
||||
ptr += tkt->length;
|
||||
|
||||
bcopy((char *) &kdc_time,ptr,4);
|
||||
ptr += 4;
|
||||
|
||||
/* guarantee null padded encrypted data to multiple of 8 bytes */
|
||||
bzero(ptr, 7);
|
||||
|
||||
c->length = (((ptr - (char *) c->dat) + 7) / 8) * 8;
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(key,key_s);
|
||||
pcbc_encrypt((C_Block *)c->dat,(C_Block *)c->dat,(long) c->length,key_s,
|
||||
key,ENCRYPT);
|
||||
#endif /* NOENCRYPTION */
|
||||
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: create_death_packet.c,v 4.9 89/01/17 16:05:59 rfrench Exp $
|
||||
* $Id: create_death_packet.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: create_death_packet.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This routine creates a packet to type AUTH_MSG_DIE which is sent to
|
||||
* the Kerberos server to make it shut down. It is used only in the
|
||||
* development environment.
|
||||
*
|
||||
* It takes a string "a_name" which is sent in the packet. A pointer
|
||||
* to the packet is returned.
|
||||
*
|
||||
* The format of the killer packet is:
|
||||
*
|
||||
* type variable data
|
||||
* or constant
|
||||
* ---- ----------- ----
|
||||
*
|
||||
* unsigned char KRB_PROT_VERSION protocol version number
|
||||
*
|
||||
* unsigned char AUTH_MSG_DIE message type
|
||||
*
|
||||
* [least significant HOST_BYTE_ORDER byte order of sender
|
||||
* bit of above field]
|
||||
*
|
||||
* string a_name presumably, name of
|
||||
* principal sending killer
|
||||
* packet
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
KTEXT
|
||||
krb_create_death_packet(a_name)
|
||||
char *a_name;
|
||||
{
|
||||
static KTEXT_ST pkt_st;
|
||||
KTEXT pkt = &pkt_st;
|
||||
|
||||
unsigned char *v = pkt->dat;
|
||||
unsigned char *t = (pkt->dat+1);
|
||||
*v = (unsigned char) KRB_PROT_VERSION;
|
||||
*t = (unsigned char) AUTH_MSG_DIE;
|
||||
*t |= HOST_BYTE_ORDER;
|
||||
(void) strcpy((char *) (pkt->dat+2),a_name);
|
||||
pkt->length = 3 + strlen(a_name);
|
||||
return pkt;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: create_ticket.c,v 4.11 89/03/22 14:43:23 jtkohl Exp $
|
||||
* $Id: create_ticket.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: create_ticket.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* Create ticket takes as arguments information that should be in a
|
||||
* ticket, and the KTEXT object in which the ticket should be
|
||||
* constructed. It then constructs a ticket and returns, leaving the
|
||||
* newly created ticket in tkt.
|
||||
* The length of the ticket is a multiple of
|
||||
* eight bytes and is in tkt->length.
|
||||
*
|
||||
* If the ticket is too long, the ticket will contain nulls.
|
||||
* The return value of the routine is undefined.
|
||||
*
|
||||
* The corresponding routine to extract information from a ticket it
|
||||
* decomp_ticket. When changes are made to this routine, the
|
||||
* corresponding changes should also be made to that file.
|
||||
*
|
||||
* The packet is built in the following format:
|
||||
*
|
||||
* variable
|
||||
* type or constant data
|
||||
* ---- ----------- ----
|
||||
*
|
||||
* tkt->length length of ticket (multiple of 8 bytes)
|
||||
*
|
||||
* tkt->dat:
|
||||
*
|
||||
* unsigned char flags namely, HOST_BYTE_ORDER
|
||||
*
|
||||
* string pname client's name
|
||||
*
|
||||
* string pinstance client's instance
|
||||
*
|
||||
* string prealm client's realm
|
||||
*
|
||||
* 4 bytes paddress client's address
|
||||
*
|
||||
* 8 bytes session session key
|
||||
*
|
||||
* 1 byte life ticket lifetime
|
||||
*
|
||||
* 4 bytes time_sec KDC timestamp
|
||||
*
|
||||
* string sname service's name
|
||||
*
|
||||
* string sinstance service's instance
|
||||
*
|
||||
* <=7 bytes null null pad to 8 byte multiple
|
||||
*
|
||||
*/
|
||||
|
||||
int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
|
||||
session, life, time_sec, sname, sinstance, key)
|
||||
KTEXT tkt; /* Gets filled in by the ticket */
|
||||
unsigned char flags; /* Various Kerberos flags */
|
||||
char *pname; /* Principal's name */
|
||||
char *pinstance; /* Principal's instance */
|
||||
char *prealm; /* Principal's authentication domain */
|
||||
long paddress; /* Net address of requesting entity */
|
||||
char *session; /* Session key inserted in ticket */
|
||||
short life; /* Lifetime of the ticket */
|
||||
long time_sec; /* Issue time and date */
|
||||
char *sname; /* Service Name */
|
||||
char *sinstance; /* Instance Name */
|
||||
C_Block key; /* Service's secret key */
|
||||
{
|
||||
Key_schedule key_s;
|
||||
register char *data; /* running index into ticket */
|
||||
|
||||
tkt->length = 0; /* Clear previous data */
|
||||
flags |= HOST_BYTE_ORDER; /* ticket byte order */
|
||||
bcopy((char *) &flags,(char *) (tkt->dat),sizeof(flags));
|
||||
data = ((char *)tkt->dat) + sizeof(flags);
|
||||
(void) strcpy(data, pname);
|
||||
data += 1 + strlen(pname);
|
||||
(void) strcpy(data, pinstance);
|
||||
data += 1 + strlen(pinstance);
|
||||
(void) strcpy(data, prealm);
|
||||
data += 1 + strlen(prealm);
|
||||
bcopy((char *) &paddress, data, 4);
|
||||
data += 4;
|
||||
|
||||
bcopy((char *) session, data, 8);
|
||||
data += 8;
|
||||
*(data++) = (char) life;
|
||||
/* issue time */
|
||||
bcopy((char *) &time_sec, data, 4);
|
||||
data += 4;
|
||||
(void) strcpy(data, sname);
|
||||
data += 1 + strlen(sname);
|
||||
(void) strcpy(data, sinstance);
|
||||
data += 1 + strlen(sinstance);
|
||||
|
||||
/* guarantee null padded ticket to multiple of 8 bytes */
|
||||
bzero(data, 7);
|
||||
tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
|
||||
|
||||
/* Check length of ticket */
|
||||
if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
|
||||
bzero(tkt->dat, tkt->length);
|
||||
tkt->length = 0;
|
||||
return KFAILURE /* XXX */;
|
||||
}
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(key,key_s);
|
||||
pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
|
||||
key_s,key,ENCRYPT);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: debug_decl.c,v 4.5 88/10/07 06:07:49 shanzer Exp $
|
||||
* $Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: debug_decl.c,v 1.2 1994/07/19 19:25:03 g89r4222 Exp $";
|
||||
#endif lint
|
||||
|
||||
/* Declare global debugging variables. */
|
||||
|
||||
int krb_ap_req_debug = 0;
|
||||
int krb_debug = 0;
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: decomp_ticket.c,v 4.12 89/05/16 18:44:46 jtkohl Exp $
|
||||
* $Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: decomp_ticket.c,v 1.2 1994/07/19 19:25:05 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This routine takes a ticket and pointers to the variables that
|
||||
* should be filled in based on the information in the ticket. It
|
||||
* fills in values for its arguments.
|
||||
*
|
||||
* Note: if the client realm field in the ticket is the null string,
|
||||
* then the "prealm" variable is filled in with the local realm (as
|
||||
* defined by KRB_REALM).
|
||||
*
|
||||
* If the ticket byte order is different than the host's byte order
|
||||
* (as indicated by the byte order bit of the "flags" field), then
|
||||
* the KDC timestamp "time_sec" is byte-swapped. The other fields
|
||||
* potentially affected by byte order, "paddress" and "session" are
|
||||
* not byte-swapped.
|
||||
*
|
||||
* The routine returns KFAILURE if any of the "pname", "pinstance",
|
||||
* or "prealm" fields is too big, otherwise it returns KSUCCESS.
|
||||
*
|
||||
* The corresponding routine to generate tickets is create_ticket.
|
||||
* When changes are made to this routine, the corresponding changes
|
||||
* should also be made to that file.
|
||||
*
|
||||
* See create_ticket.c for the format of the ticket packet.
|
||||
*/
|
||||
|
||||
decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
|
||||
life, time_sec, sname, sinstance, key, key_s)
|
||||
KTEXT tkt; /* The ticket to be decoded */
|
||||
unsigned char *flags; /* Kerberos ticket flags */
|
||||
char *pname; /* Authentication name */
|
||||
char *pinstance; /* Principal's instance */
|
||||
char *prealm; /* Principal's authentication domain */
|
||||
unsigned long *paddress; /* Net address of entity
|
||||
* requesting ticket */
|
||||
C_Block session; /* Session key inserted in ticket */
|
||||
int *life; /* Lifetime of the ticket */
|
||||
unsigned long *time_sec; /* Issue time and date */
|
||||
char *sname; /* Service name */
|
||||
char *sinstance; /* Service instance */
|
||||
C_Block key; /* Service's secret key
|
||||
* (to decrypt the ticket) */
|
||||
Key_schedule key_s; /* The precomputed key schedule */
|
||||
{
|
||||
static int tkt_swap_bytes;
|
||||
unsigned char *uptr;
|
||||
char *ptr = (char *)tkt->dat;
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,(long)tkt->length,
|
||||
key_s,key,DECRYPT);
|
||||
#endif /* ! NOENCRYPTION */
|
||||
|
||||
*flags = *ptr; /* get flags byte */
|
||||
ptr += sizeof(*flags);
|
||||
tkt_swap_bytes = 0;
|
||||
if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
|
||||
tkt_swap_bytes++;
|
||||
|
||||
if (strlen(ptr) > ANAME_SZ)
|
||||
return(KFAILURE);
|
||||
(void) strcpy(pname,ptr); /* pname */
|
||||
ptr += strlen(pname) + 1;
|
||||
|
||||
if (strlen(ptr) > INST_SZ)
|
||||
return(KFAILURE);
|
||||
(void) strcpy(pinstance,ptr); /* instance */
|
||||
ptr += strlen(pinstance) + 1;
|
||||
|
||||
if (strlen(ptr) > REALM_SZ)
|
||||
return(KFAILURE);
|
||||
(void) strcpy(prealm,ptr); /* realm */
|
||||
ptr += strlen(prealm) + 1;
|
||||
/* temporary hack until realms are dealt with properly */
|
||||
if (*prealm == 0)
|
||||
(void) strcpy(prealm,KRB_REALM);
|
||||
|
||||
bcopy(ptr,(char *)paddress,4); /* net address */
|
||||
ptr += 4;
|
||||
|
||||
bcopy(ptr,(char *)session,8); /* session key */
|
||||
ptr+= 8;
|
||||
#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
|
||||
if (tkt_swap_bytes)
|
||||
swap_C_Block(session);
|
||||
#endif
|
||||
|
||||
/* get lifetime, being certain we don't get negative lifetimes */
|
||||
uptr = (unsigned char *) ptr++;
|
||||
*life = (int) *uptr;
|
||||
|
||||
bcopy(ptr,(char *) time_sec,4); /* issue time */
|
||||
ptr += 4;
|
||||
if (tkt_swap_bytes)
|
||||
swap_u_long(*time_sec);
|
||||
|
||||
(void) strcpy(sname,ptr); /* service name */
|
||||
ptr += 1 + strlen(sname);
|
||||
|
||||
(void) strcpy(sinstance,ptr); /* instance */
|
||||
ptr += 1 + strlen(sinstance);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,265 +0,0 @@
|
||||
/* -
|
||||
* Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from a specification based on software
|
||||
* which forms part of the 4.4BSD-Lite distribution, which was developed
|
||||
* by the University of California and its contributors.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the entire comment,
|
||||
* including the above copyright notice, this list of conditions
|
||||
* and the following disclaimer, verbatim, at the beginning of
|
||||
* the source file.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Geoffrey M. Rehmet
|
||||
* 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: des_rw.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routines for reading and writing DES encrypted messages onto sockets.
|
||||
* (These routines will fail if non-blocking I/O is used.)
|
||||
*
|
||||
* When a message is written, its length is first transmitted as an int,
|
||||
* in network byte order. The encrypted message is then transmitted,
|
||||
* to a multiple of 8 bytes. Messages shorter than 8 bytes are right
|
||||
* justified into a buffer of length 8 bytes, and the remainder of the
|
||||
* buffer is filled with random garbage (before encryption):
|
||||
*
|
||||
* DDD -------->--+--------+
|
||||
* | |
|
||||
* +--+--+--+--+--+--+--+--+
|
||||
* |x |x |x |x |x |D |D |D |
|
||||
* +--+--+--+--+--+--+--+--+
|
||||
* | garbage | data |
|
||||
* | |
|
||||
* +-----------------------+----> des_pcbc_encrypt() -->
|
||||
*
|
||||
* (Note that the length field sent before the actual message specifies
|
||||
* the number of data bytes, not the length of the entire padded message.
|
||||
*
|
||||
* When data is read, if the message received is longer than the number
|
||||
* of bytes requested, then the remaining bytes are stored until the
|
||||
* following call to des_read(). If the number of bytes received is
|
||||
* less then the number of bytes received, then only the number of bytes
|
||||
* actually received is returned.
|
||||
*
|
||||
* This interface corresponds with the original des_rw.c, except for the
|
||||
* bugs in des_read() in the original 4.4BSD version. (One bug is
|
||||
* normally not visible, due to undocumented behaviour of
|
||||
* des_pcbc_encrypt() in the original MIT libdes.)
|
||||
*
|
||||
* XXX Todo:
|
||||
* 1) Give better error returns on writes
|
||||
* 2) Improve error checking on reads
|
||||
* 3) Get rid of need for extern decl. of krb_net_read()
|
||||
* 4) Tidy garbage generation a bit
|
||||
* 5) Make the above comment more readable
|
||||
*/
|
||||
|
||||
#ifdef CRYPT
|
||||
#ifdef KERBEROS
|
||||
|
||||
#ifndef BUFFER_LEN
|
||||
#define BUFFER_LEN 10240
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <kerberosIV/des.h>
|
||||
#include <kerberosIV/krb.h>
|
||||
|
||||
extern int krb_net_read(int fd, void * data, size_t length);
|
||||
extern int des_pcbc_encrypt(des_cblock *input, des_cblock *output,
|
||||
register long length,
|
||||
des_key_schedule schedule,
|
||||
des_cblock *ivec,
|
||||
int encrypt);
|
||||
|
||||
static bit_64 des_key;
|
||||
static des_key_schedule key_sched;
|
||||
|
||||
/*
|
||||
* Buffer for storing extra data when more data is received, then was
|
||||
* actually requested in des_read().
|
||||
*/
|
||||
static u_char des_buff[BUFFER_LEN];
|
||||
static u_char buffer[BUFFER_LEN];
|
||||
static unsigned stored = 0;
|
||||
static u_char *buff_ptr = buffer;
|
||||
|
||||
/*
|
||||
* Set the encryption key for des_read() and des_write().
|
||||
* inkey is the initial vector for the DES encryption, while insched is
|
||||
* the DES key, in unwrapped form.
|
||||
*/
|
||||
void des_set_key(inkey, insched)
|
||||
bit_64 *inkey;
|
||||
u_char *insched;
|
||||
{
|
||||
bcopy(inkey, &des_key, sizeof(bit_64));
|
||||
bcopy(insched, &key_sched, sizeof(des_key_schedule));
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the key schedule, and initial vector, which were previously
|
||||
* stored in static vars by des_set_key().
|
||||
*/
|
||||
void des_clear_key()
|
||||
{
|
||||
bzero(&des_key, sizeof(des_cblock));
|
||||
bzero(&key_sched, sizeof(des_key_schedule));
|
||||
}
|
||||
|
||||
int des_read(fd, buf, len)
|
||||
int fd;
|
||||
register char * buf;
|
||||
int len;
|
||||
{
|
||||
int msg_length; /* length of actual message data */
|
||||
int pad_length; /* length of padded message */
|
||||
int nread; /* number of bytes actually read */
|
||||
int nreturned = 0;
|
||||
|
||||
if(stored >= len) {
|
||||
bcopy(buff_ptr, buf, len);
|
||||
stored -= len;
|
||||
buff_ptr += len;
|
||||
return(len);
|
||||
} else {
|
||||
if (stored) {
|
||||
bcopy(buff_ptr, buf, stored);
|
||||
nreturned = stored;
|
||||
len -= stored;
|
||||
stored = 0;
|
||||
buff_ptr = buffer;
|
||||
} else {
|
||||
nreturned = 0;
|
||||
buff_ptr = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
nread = krb_net_read(fd, &msg_length, sizeof(msg_length));
|
||||
if(nread != (int)(sizeof(msg_length)))
|
||||
return(0);
|
||||
|
||||
msg_length = ntohl(msg_length);
|
||||
pad_length = roundup(msg_length, 8);
|
||||
|
||||
nread = krb_net_read(fd, des_buff, pad_length);
|
||||
if(nread != pad_length)
|
||||
return(0);
|
||||
|
||||
des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr,
|
||||
(msg_length < 8 ? 8 : msg_length),
|
||||
key_sched, (des_cblock*) &des_key, DES_DECRYPT);
|
||||
|
||||
|
||||
if(msg_length < 8)
|
||||
buff_ptr += (8 - msg_length);
|
||||
stored = msg_length;
|
||||
|
||||
if(stored >= len) {
|
||||
bcopy(buff_ptr, buf, len);
|
||||
stored -= len;
|
||||
buff_ptr += len;
|
||||
nreturned += len;
|
||||
} else {
|
||||
bcopy(buff_ptr, buf, stored);
|
||||
nreturned += stored;
|
||||
stored = 0;
|
||||
}
|
||||
|
||||
return(nreturned);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a message onto a file descriptor (generally a socket), using
|
||||
* DES to encrypt the message.
|
||||
*/
|
||||
int des_write(fd, buf, len)
|
||||
int fd;
|
||||
char * buf;
|
||||
int len;
|
||||
{
|
||||
static int seeded = 0;
|
||||
char garbage[8];
|
||||
long rnd;
|
||||
int pad_len;
|
||||
int write_len;
|
||||
int nwritten = 0;
|
||||
int i;
|
||||
char *data;
|
||||
|
||||
if(len < 8) {
|
||||
/*
|
||||
* Right justify the message in 8 bytes of random garbage.
|
||||
*/
|
||||
if(!seeded) {
|
||||
seeded = 1;
|
||||
srandom((unsigned)time(NULL));
|
||||
}
|
||||
|
||||
for(i = 0 ; i < 8 ; i+= sizeof(long)) {
|
||||
rnd = random();
|
||||
bcopy(&rnd, garbage+i,
|
||||
(i <= (8 - sizeof(long)))?sizeof(long):(8-i));
|
||||
}
|
||||
bcopy(buf, garbage + 8 - len, len);
|
||||
data = garbage;
|
||||
pad_len = 8;
|
||||
} else {
|
||||
data = buf;
|
||||
pad_len = roundup(len, 8);
|
||||
}
|
||||
|
||||
des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff,
|
||||
(len < 8)?8:len, key_sched, (des_cblock*) &des_key, DES_ENCRYPT);
|
||||
|
||||
|
||||
write_len = htonl(len);
|
||||
if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len))
|
||||
return(-1);
|
||||
if(write(fd, des_buff, pad_len) != pad_len)
|
||||
return(-1);
|
||||
|
||||
return(len);
|
||||
}
|
||||
|
||||
#endif /* KERBEROS */
|
||||
#endif /* CRYPT */
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: dest_tkt.c,v 4.9 89/10/02 16:23:07 jtkohl Exp $
|
||||
* $Id: dest_tkt.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: dest_tkt.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef TKT_SHMEM
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* dest_tkt() is used to destroy the ticket store upon logout.
|
||||
* If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
|
||||
* Otherwise the function returns RET_OK on success, KFAILURE on
|
||||
* failure.
|
||||
*
|
||||
* The ticket file (TKT_FILE) is defined in "krb.h".
|
||||
*/
|
||||
|
||||
dest_tkt()
|
||||
{
|
||||
char *file = TKT_FILE;
|
||||
int i,fd;
|
||||
extern int errno;
|
||||
struct stat statb;
|
||||
char buf[BUFSIZ];
|
||||
#ifdef TKT_SHMEM
|
||||
char shmidname[MAXPATHLEN];
|
||||
#endif /* TKT_SHMEM */
|
||||
|
||||
errno = 0;
|
||||
if (lstat(file,&statb) < 0)
|
||||
goto out;
|
||||
|
||||
if (!(statb.st_mode & S_IFREG)
|
||||
#ifdef notdef
|
||||
|| statb.st_mode & 077
|
||||
#endif
|
||||
)
|
||||
goto out;
|
||||
|
||||
if ((fd = open(file, O_RDWR, 0)) < 0)
|
||||
goto out;
|
||||
|
||||
bzero(buf, BUFSIZ);
|
||||
|
||||
for (i = 0; i < statb.st_size; i += BUFSIZ)
|
||||
if (write(fd, buf, BUFSIZ) != BUFSIZ) {
|
||||
(void) fsync(fd);
|
||||
(void) close(fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
(void) fsync(fd);
|
||||
(void) close(fd);
|
||||
|
||||
(void) unlink(file);
|
||||
|
||||
out:
|
||||
if (errno == ENOENT) return RET_TKFIL;
|
||||
else if (errno != 0) return KFAILURE;
|
||||
#ifdef TKT_SHMEM
|
||||
/*
|
||||
* handle the shared memory case
|
||||
*/
|
||||
(void) strcpy(shmidname, file);
|
||||
(void) strcat(shmidname, ".shm");
|
||||
if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
|
||||
return(i);
|
||||
#endif /* TKT_SHMEM */
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: extract_ticket.c,v 4.6 88/10/07 06:08:15 shanzer Exp $
|
||||
* $Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: extract_ticket.c,v 1.2 1994/07/19 19:25:08 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This routine is obsolete.
|
||||
*
|
||||
* This routine accepts the ciphertext returned by kerberos and
|
||||
* extracts the nth ticket. It also fills in the variables passed as
|
||||
* session, liftime and kvno.
|
||||
*/
|
||||
|
||||
extract_ticket(cipher,n,session,lifetime,kvno,realm,ticket)
|
||||
KTEXT cipher; /* The ciphertext */
|
||||
int n; /* Which ticket */
|
||||
char *session; /* The session key for this tkt */
|
||||
int *lifetime; /* The life of this ticket */
|
||||
int *kvno; /* The kvno for the service */
|
||||
char *realm; /* Realm in which tkt issued */
|
||||
KTEXT ticket; /* The ticket itself */
|
||||
{
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
/* Start after the ticket lengths */
|
||||
ptr = (char *) cipher->dat;
|
||||
ptr = ptr + 1 + (int) *(cipher->dat);
|
||||
|
||||
/* Step through earlier tickets */
|
||||
for (i = 1; i < n; i++)
|
||||
ptr = ptr + 11 + strlen(ptr+10) + (int) *(cipher->dat+i);
|
||||
bcopy(ptr, (char *) session, 8); /* Save the session key */
|
||||
ptr += 8;
|
||||
*lifetime = *(ptr++); /* Save the life of the ticket */
|
||||
*kvno = *(ptr++); /* Save the kvno */
|
||||
(void) strcpy(realm,ptr); /* instance */
|
||||
ptr += strlen(realm) + 1;
|
||||
|
||||
/* Save the ticket if its length is non zero */
|
||||
ticket->length = *(cipher->dat+n);
|
||||
if (ticket->length)
|
||||
bcopy(ptr, (char *) (ticket->dat), ticket->length);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: fgetst.c,v 4.0 89/01/23 10:08:31 jtkohl Exp $
|
||||
* $Id: fgetst.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: fgetst.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* fgetst takes a file descriptor, a character pointer, and a count.
|
||||
* It reads from the file it has either read "count" characters, or
|
||||
* until it reads a null byte. When finished, what has been read exists
|
||||
* in "s". If "count" characters were actually read, the last is changed
|
||||
* to a null, so the returned string is always null-terminated. fgetst
|
||||
* returns the number of characters read, including the null terminator.
|
||||
*/
|
||||
|
||||
fgetst(f, s, n)
|
||||
FILE *f;
|
||||
register char *s;
|
||||
int n;
|
||||
{
|
||||
register count = n;
|
||||
int ch; /* NOT char; otherwise you don't see EOF */
|
||||
|
||||
while ((ch = getc(f)) != EOF && ch && --count) {
|
||||
*s++ = ch;
|
||||
}
|
||||
*s = '\0';
|
||||
return (n - count);
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_ad_tkt.c,v 4.15 89/07/07 15:18:51 jtkohl Exp $
|
||||
* $Id: get_ad_tkt.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: get_ad_tkt.c,v 1.1.1.1 1994/09/30 14:49:59 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <des.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* use the bsd time.h struct defs for PC too! */
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
extern int krb_debug;
|
||||
|
||||
struct timeval tt_local = { 0, 0 };
|
||||
|
||||
int swap_bytes;
|
||||
unsigned long rep_err_code;
|
||||
|
||||
/*
|
||||
* get_ad_tkt obtains a new service ticket from Kerberos, using
|
||||
* the ticket-granting ticket which must be in the ticket file.
|
||||
* It is typically called by krb_mk_req() when the client side
|
||||
* of an application is creating authentication information to be
|
||||
* sent to the server side.
|
||||
*
|
||||
* get_ad_tkt takes four arguments: three pointers to strings which
|
||||
* contain the name, instance, and realm of the service for which the
|
||||
* ticket is to be obtained; and an integer indicating the desired
|
||||
* lifetime of the ticket.
|
||||
*
|
||||
* It returns an error status if the ticket couldn't be obtained,
|
||||
* or AD_OK if all went well. The ticket is stored in the ticket
|
||||
* cache.
|
||||
*
|
||||
* The request sent to the Kerberos ticket-granting service looks
|
||||
* like this:
|
||||
*
|
||||
* pkt->dat
|
||||
*
|
||||
* TEXT original contents of authenticator+ticket
|
||||
* pkt->dat built in krb_mk_req call
|
||||
*
|
||||
* 4 bytes time_ws always 0 (?)
|
||||
* char lifetime lifetime argument passed
|
||||
* string service service name argument
|
||||
* string sinstance service instance arg.
|
||||
*
|
||||
* See "prot.h" for the reply packet layout and definitions of the
|
||||
* extraction macros like pkt_version(), pkt_msg_type(), etc.
|
||||
*/
|
||||
|
||||
get_ad_tkt(service,sinstance,realm,lifetime)
|
||||
char *service;
|
||||
char *sinstance;
|
||||
char *realm;
|
||||
int lifetime;
|
||||
{
|
||||
static KTEXT_ST pkt_st;
|
||||
KTEXT pkt = & pkt_st; /* Packet to KDC */
|
||||
static KTEXT_ST rpkt_st;
|
||||
KTEXT rpkt = &rpkt_st; /* Returned packet */
|
||||
static KTEXT_ST cip_st;
|
||||
KTEXT cip = &cip_st; /* Returned Ciphertext */
|
||||
static KTEXT_ST tkt_st;
|
||||
KTEXT tkt = &tkt_st; /* Current ticket */
|
||||
C_Block ses; /* Session key for tkt */
|
||||
CREDENTIALS cr;
|
||||
int kvno; /* Kvno for session key */
|
||||
char lrealm[REALM_SZ];
|
||||
C_Block key; /* Key for decrypting cipher */
|
||||
Key_schedule key_s;
|
||||
long time_ws = 0;
|
||||
|
||||
char s_name[SNAME_SZ];
|
||||
char s_instance[INST_SZ];
|
||||
int msg_byte_order;
|
||||
int kerror;
|
||||
char rlm[REALM_SZ];
|
||||
char *ptr;
|
||||
|
||||
unsigned long kdc_time; /* KDC time */
|
||||
|
||||
if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
|
||||
return(kerror);
|
||||
|
||||
/* Create skeleton of packet to be sent */
|
||||
(void) gettimeofday(&tt_local,(struct timezone *) 0);
|
||||
|
||||
pkt->length = 0;
|
||||
|
||||
/*
|
||||
* Look for the session key (and other stuff we don't need)
|
||||
* in the ticket file for krbtgt.realm@lrealm where "realm"
|
||||
* is the service's realm (passed in "realm" argument) and
|
||||
* lrealm is the realm of our initial ticket. If we don't
|
||||
* have this, we will try to get it.
|
||||
*/
|
||||
|
||||
if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
|
||||
/*
|
||||
* If realm == lrealm, we have no hope, so let's not even try.
|
||||
*/
|
||||
if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
|
||||
return(AD_NOTGT);
|
||||
else{
|
||||
if ((kerror =
|
||||
get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS)
|
||||
return(kerror);
|
||||
if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
|
||||
return(kerror);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make up a request packet to the "krbtgt.realm@lrealm".
|
||||
* Start by calling krb_mk_req() which puts ticket+authenticator
|
||||
* into "pkt". Then tack other stuff on the end.
|
||||
*/
|
||||
|
||||
kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
|
||||
|
||||
if (kerror)
|
||||
return(AD_NOTGT);
|
||||
|
||||
/* timestamp */
|
||||
bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4);
|
||||
pkt->length += 4;
|
||||
*(pkt->dat+(pkt->length)++) = (char) lifetime;
|
||||
(void) strcpy((char *) (pkt->dat+pkt->length),service);
|
||||
pkt->length += 1 + strlen(service);
|
||||
(void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
|
||||
pkt->length += 1 + strlen(sinstance);
|
||||
|
||||
rpkt->length = 0;
|
||||
|
||||
/* Send the request to the local ticket-granting server */
|
||||
if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
|
||||
|
||||
/* check packet version of the returned packet */
|
||||
if (pkt_version(rpkt) != KRB_PROT_VERSION )
|
||||
return(INTK_PROT);
|
||||
|
||||
/* Check byte order */
|
||||
msg_byte_order = pkt_msg_type(rpkt) & 1;
|
||||
swap_bytes = 0;
|
||||
if (msg_byte_order != HOST_BYTE_ORDER)
|
||||
swap_bytes++;
|
||||
|
||||
switch (pkt_msg_type(rpkt) & ~1) {
|
||||
case AUTH_MSG_KDC_REPLY:
|
||||
break;
|
||||
case AUTH_MSG_ERR_REPLY:
|
||||
bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4);
|
||||
if (swap_bytes)
|
||||
swap_u_long(rep_err_code);
|
||||
return(rep_err_code);
|
||||
|
||||
default:
|
||||
return(INTK_PROT);
|
||||
}
|
||||
|
||||
/* Extract the ciphertext */
|
||||
cip->length = pkt_clen(rpkt); /* let clen do the swap */
|
||||
|
||||
bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length);
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(cr.session,key_s);
|
||||
pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,(long)cip->length,
|
||||
key_s,cr.session,DECRYPT);
|
||||
#endif
|
||||
/* Get rid of all traces of key */
|
||||
bzero((char *) cr.session, sizeof(key));
|
||||
bzero((char *) key_s, sizeof(key_s));
|
||||
|
||||
ptr = (char *) cip->dat;
|
||||
|
||||
bcopy(ptr,(char *)ses,8);
|
||||
ptr += 8;
|
||||
|
||||
(void) strcpy(s_name,ptr);
|
||||
ptr += strlen(s_name) + 1;
|
||||
|
||||
(void) strcpy(s_instance,ptr);
|
||||
ptr += strlen(s_instance) + 1;
|
||||
|
||||
(void) strcpy(rlm,ptr);
|
||||
ptr += strlen(rlm) + 1;
|
||||
|
||||
lifetime = (unsigned long) ptr[0];
|
||||
kvno = (unsigned long) ptr[1];
|
||||
tkt->length = (int) ptr[2];
|
||||
ptr += 3;
|
||||
bcopy(ptr,(char *)(tkt->dat),tkt->length);
|
||||
ptr += tkt->length;
|
||||
|
||||
if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
|
||||
strcmp(rlm, realm)) /* not what we asked for */
|
||||
return(INTK_ERR); /* we need a better code here XXX */
|
||||
|
||||
/* check KDC time stamp */
|
||||
bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
|
||||
if (swap_bytes) swap_u_long(kdc_time);
|
||||
|
||||
ptr += 4;
|
||||
|
||||
(void) gettimeofday(&tt_local,(struct timezone *) 0);
|
||||
if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
|
||||
return(RD_AP_TIME); /* XXX should probably be better
|
||||
code */
|
||||
}
|
||||
|
||||
if (kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime,
|
||||
kvno,tkt,tt_local.tv_sec))
|
||||
return(kerror);
|
||||
|
||||
return(AD_OK);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_admhst.c,v 4.0 89/01/23 10:08:55 jtkohl Exp $
|
||||
* $Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: get_admhst.c,v 1.2 1994/07/19 19:25:13 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Given a Kerberos realm, find a host on which the Kerberos database
|
||||
* administration server can be found.
|
||||
*
|
||||
* krb_get_admhst takes a pointer to be filled in, a pointer to the name
|
||||
* of the realm for which a server is desired, and an integer n, and
|
||||
* returns (in h) the nth administrative host entry from the configuration
|
||||
* file (KRB_CONF, defined in "krb.h") associated with the specified realm.
|
||||
*
|
||||
* On error, get_admhst returns KFAILURE. If all goes well, the routine
|
||||
* returns KSUCCESS.
|
||||
*
|
||||
* For the format of the KRB_CONF file, see comments describing the routine
|
||||
* krb_get_krbhst().
|
||||
*
|
||||
* This is a temporary hack to allow us to find the nearest system running
|
||||
* a Kerberos admin server. In the long run, this functionality will be
|
||||
* provided by a nameserver.
|
||||
*/
|
||||
|
||||
krb_get_admhst(h, r, n)
|
||||
char *h;
|
||||
char *r;
|
||||
int n;
|
||||
{
|
||||
FILE *cnffile;
|
||||
char tr[REALM_SZ];
|
||||
char linebuf[BUFSIZ];
|
||||
char scratch[64];
|
||||
register int i;
|
||||
|
||||
if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
|
||||
return(KFAILURE);
|
||||
}
|
||||
if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
|
||||
/* error reading */
|
||||
(void) fclose(cnffile);
|
||||
return(KFAILURE);
|
||||
}
|
||||
if (!index(linebuf, '\n')) {
|
||||
/* didn't all fit into buffer, punt */
|
||||
(void) fclose(cnffile);
|
||||
return(KFAILURE);
|
||||
}
|
||||
for (i = 0; i < n; ) {
|
||||
/* run through the file, looking for admin host */
|
||||
if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
|
||||
(void) fclose(cnffile);
|
||||
return(KFAILURE);
|
||||
}
|
||||
/* need to scan for a token after 'admin' to make sure that
|
||||
admin matched correctly */
|
||||
if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3)
|
||||
continue;
|
||||
if (!strcmp(tr,r))
|
||||
i++;
|
||||
}
|
||||
(void) fclose(cnffile);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_cred.c,v 4.10 89/05/31 17:46:22 jtkohl Exp $
|
||||
* $Id: get_cred.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: get_cred.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
|
||||
/*
|
||||
* krb_get_cred takes a service name, instance, and realm, and a
|
||||
* structure of type CREDENTIALS to be filled in with ticket
|
||||
* information. It then searches the ticket file for the appropriate
|
||||
* ticket and fills in the structure with the corresponding
|
||||
* information from the file. If successful, it returns KSUCCESS.
|
||||
* On failure it returns a Kerberos error code.
|
||||
*/
|
||||
|
||||
krb_get_cred(service,instance,realm,c)
|
||||
char *service; /* Service name */
|
||||
char *instance; /* Instance */
|
||||
char *realm; /* Auth domain */
|
||||
CREDENTIALS *c; /* Credentials struct */
|
||||
{
|
||||
int tf_status; /* return value of tf function calls */
|
||||
|
||||
/* Open ticket file and lock it for shared reading */
|
||||
if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS)
|
||||
return(tf_status);
|
||||
|
||||
/* Copy principal's name and instance into the CREDENTIALS struc c */
|
||||
|
||||
if ( (tf_status = tf_get_pname(c->pname)) != KSUCCESS ||
|
||||
(tf_status = tf_get_pinst(c->pinst)) != KSUCCESS )
|
||||
return (tf_status);
|
||||
|
||||
/* Search for requested service credentials and copy into c */
|
||||
|
||||
while ((tf_status = tf_get_cred(c)) == KSUCCESS) {
|
||||
/* Is this the right ticket? */
|
||||
if ((strcmp(c->service,service) == 0) &&
|
||||
(strcmp(c->instance,instance) == 0) &&
|
||||
(strcmp(c->realm,realm) == 0))
|
||||
break;
|
||||
}
|
||||
(void) tf_close();
|
||||
|
||||
if (tf_status == EOF)
|
||||
return (GC_NOTKT);
|
||||
return(tf_status);
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_in_tkt.c,v 4.12 89/07/18 16:32:56 jtkohl Exp $
|
||||
* $Id: get_in_tkt.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: get_in_tkt.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file contains two routines: passwd_to_key() converts
|
||||
* a password into a DES key (prompting for the password if
|
||||
* not supplied), and krb_get_pw_in_tkt() gets an initial ticket for
|
||||
* a user.
|
||||
*/
|
||||
|
||||
/*
|
||||
* passwd_to_key(): given a password, return a DES key.
|
||||
* There are extra arguments here which (used to be?)
|
||||
* used by srvtab_to_key().
|
||||
*
|
||||
* If the "passwd" argument is not null, generate a DES
|
||||
* key from it, using string_to_key().
|
||||
*
|
||||
* If the "passwd" argument is null, call des_read_password()
|
||||
* to prompt for a password and then convert it into a DES key.
|
||||
*
|
||||
* In either case, the resulting key is put in the "key" argument,
|
||||
* and 0 is returned.
|
||||
*/
|
||||
|
||||
/*ARGSUSED */
|
||||
static int passwd_to_key(user,instance,realm,passwd,key)
|
||||
char *user, *instance, *realm, *passwd;
|
||||
C_Block key;
|
||||
{
|
||||
#ifdef NOENCRYPTION
|
||||
if (!passwd)
|
||||
placebo_read_password(key, "Password: ", 0);
|
||||
#else
|
||||
if (passwd)
|
||||
string_to_key(passwd,key);
|
||||
else
|
||||
des_read_password(key,"Password: ",0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* krb_get_pw_in_tkt() takes the name of the server for which the initial
|
||||
* ticket is to be obtained, the name of the principal the ticket is
|
||||
* for, the desired lifetime of the ticket, and the user's password.
|
||||
* It passes its arguments on to krb_get_in_tkt(), which contacts
|
||||
* Kerberos to get the ticket, decrypts it using the password provided,
|
||||
* and stores it away for future use.
|
||||
*
|
||||
* krb_get_pw_in_tkt() passes two additional arguments to krb_get_in_tkt():
|
||||
* the name of a routine (passwd_to_key()) to be used to get the
|
||||
* password in case the "password" argument is null and NULL for the
|
||||
* decryption procedure indicating that krb_get_in_tkt should use the
|
||||
* default method of decrypting the response from the KDC.
|
||||
*
|
||||
* The result of the call to krb_get_in_tkt() is returned.
|
||||
*/
|
||||
|
||||
krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password)
|
||||
char *user, *instance, *realm, *service, *sinstance;
|
||||
int life;
|
||||
char *password;
|
||||
{
|
||||
return(krb_get_in_tkt(user,instance,realm,service,sinstance,life,
|
||||
passwd_to_key, NULL, password));
|
||||
}
|
||||
|
||||
#ifdef NOENCRYPTION
|
||||
/*
|
||||
* $Source: /home/ncvs/src/eBones/krb/get_in_tkt.c,v $
|
||||
* $Author: csgr $
|
||||
*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <mit-copyright.h>.
|
||||
*
|
||||
* This routine prints the supplied string to standard
|
||||
* output as a prompt, and reads a password string without
|
||||
* echoing.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid_read_password_c[] =
|
||||
"Bones$Header: /home/ncvs/src/eBones/krb/get_in_tkt.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <des.h>
|
||||
#include "conf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef BSDUNIX
|
||||
#include <strings.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#else
|
||||
char *strcpy();
|
||||
int strcmp();
|
||||
#endif
|
||||
|
||||
#ifdef BSDUNIX
|
||||
static jmp_buf env;
|
||||
#endif
|
||||
|
||||
#ifdef BSDUNIX
|
||||
static void sig_restore();
|
||||
static push_signals(), pop_signals();
|
||||
int placebo_read_pw_string();
|
||||
#endif
|
||||
|
||||
/*** Routines ****************************************************** */
|
||||
int
|
||||
placebo_read_password(k,prompt,verify)
|
||||
des_cblock *k;
|
||||
char *prompt;
|
||||
int verify;
|
||||
{
|
||||
int ok;
|
||||
char key_string[BUFSIZ];
|
||||
|
||||
#ifdef BSDUNIX
|
||||
if (setjmp(env)) {
|
||||
ok = -1;
|
||||
goto lose;
|
||||
}
|
||||
#endif
|
||||
|
||||
ok = placebo_read_pw_string(key_string, BUFSIZ, prompt, verify);
|
||||
if (ok == 0)
|
||||
bzero(k, sizeof(C_Block));
|
||||
|
||||
lose:
|
||||
bzero(key_string, sizeof (key_string));
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* This version just returns the string, doesn't map to key.
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*/
|
||||
|
||||
int
|
||||
placebo_read_pw_string(s,max,prompt,verify)
|
||||
char *s;
|
||||
int max;
|
||||
char *prompt;
|
||||
int verify;
|
||||
{
|
||||
int ok = 0;
|
||||
char *ptr;
|
||||
|
||||
#ifdef BSDUNIX
|
||||
jmp_buf old_env;
|
||||
struct sgttyb tty_state;
|
||||
#endif
|
||||
char key_string[BUFSIZ];
|
||||
|
||||
if (max > BUFSIZ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef BSDUNIX
|
||||
bcopy(old_env, env, sizeof(env));
|
||||
if (setjmp(env))
|
||||
goto lose;
|
||||
|
||||
/* save terminal state*/
|
||||
if (ioctl(0,TIOCGETP,&tty_state) == -1)
|
||||
return -1;
|
||||
|
||||
push_signals();
|
||||
/* Turn off echo */
|
||||
tty_state.sg_flags &= ~ECHO;
|
||||
if (ioctl(0,TIOCSETP,&tty_state) == -1)
|
||||
return -1;
|
||||
#endif
|
||||
while (!ok) {
|
||||
printf(prompt);
|
||||
fflush(stdout);
|
||||
#ifdef CROSSMSDOS
|
||||
h19line(s,sizeof(s),0);
|
||||
if (!strlen(s))
|
||||
continue;
|
||||
#else
|
||||
if (!fgets(s, max, stdin)) {
|
||||
clearerr(stdin);
|
||||
continue;
|
||||
}
|
||||
if ((ptr = index(s, '\n')))
|
||||
*ptr = '\0';
|
||||
#endif
|
||||
if (verify) {
|
||||
printf("\nVerifying, please re-enter %s",prompt);
|
||||
fflush(stdout);
|
||||
#ifdef CROSSMSDOS
|
||||
h19line(key_string,sizeof(key_string),0);
|
||||
if (!strlen(key_string))
|
||||
continue;
|
||||
#else
|
||||
if (!fgets(key_string, sizeof(key_string), stdin)) {
|
||||
clearerr(stdin);
|
||||
continue;
|
||||
}
|
||||
if ((ptr = index(key_string, '\n')))
|
||||
*ptr = '\0';
|
||||
#endif
|
||||
if (strcmp(s,key_string)) {
|
||||
printf("\n\07\07Mismatch - try again\n");
|
||||
fflush(stdout);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
#ifdef BSDUNIX
|
||||
lose:
|
||||
if (!ok)
|
||||
bzero(s, max);
|
||||
printf("\n");
|
||||
/* turn echo back on */
|
||||
tty_state.sg_flags |= ECHO;
|
||||
if (ioctl(0,TIOCSETP,&tty_state))
|
||||
ok = 0;
|
||||
pop_signals();
|
||||
bcopy(env, old_env, sizeof(env));
|
||||
#endif
|
||||
if (verify)
|
||||
bzero(key_string, sizeof (key_string));
|
||||
s[max-1] = 0; /* force termination */
|
||||
return !ok; /* return nonzero if not okay */
|
||||
}
|
||||
|
||||
#ifdef BSDUNIX
|
||||
/*
|
||||
* this can be static since we should never have more than
|
||||
* one set saved....
|
||||
*/
|
||||
#ifdef POSIX
|
||||
static void (*old_sigfunc[NSIG])();
|
||||
#else
|
||||
static int (*old_sigfunc[NSIG])();
|
||||
#endif POSIX
|
||||
|
||||
static push_signals()
|
||||
{
|
||||
register i;
|
||||
for (i = 0; i < NSIG; i++)
|
||||
old_sigfunc[i] = signal(i,sig_restore);
|
||||
}
|
||||
|
||||
static pop_signals()
|
||||
{
|
||||
register i;
|
||||
for (i = 0; i < NSIG; i++)
|
||||
signal(i,old_sigfunc[i]);
|
||||
}
|
||||
|
||||
static void sig_restore(sig,code,scp)
|
||||
int sig,code;
|
||||
struct sigcontext *scp;
|
||||
{
|
||||
longjmp(env,1);
|
||||
}
|
||||
#endif
|
||||
#endif /* NOENCRYPTION */
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_krbhst.c,v 4.8 89/01/22 20:00:29 rfrench Exp $
|
||||
* $Id: get_krbhst.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: get_krbhst.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* Given a Kerberos realm, find a host on which the Kerberos authenti-
|
||||
* cation server can be found.
|
||||
*
|
||||
* krb_get_krbhst takes a pointer to be filled in, a pointer to the name
|
||||
* of the realm for which a server is desired, and an integer, n, and
|
||||
* returns (in h) the nth entry from the configuration file (KRB_CONF,
|
||||
* defined in "krb.h") associated with the specified realm.
|
||||
*
|
||||
* On end-of-file, krb_get_krbhst returns KFAILURE. If n=1 and the
|
||||
* configuration file does not exist, krb_get_krbhst will return KRB_HOST
|
||||
* (also defined in "krb.h"). If all goes well, the routine returnes
|
||||
* KSUCCESS.
|
||||
*
|
||||
* The KRB_CONF file contains the name of the local realm in the first
|
||||
* line (not used by this routine), followed by lines indicating realm/host
|
||||
* entries. The words "admin server" following the hostname indicate that
|
||||
* the host provides an administrative database server.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* ATHENA.MIT.EDU
|
||||
* ATHENA.MIT.EDU kerberos-1.mit.edu admin server
|
||||
* ATHENA.MIT.EDU kerberos-2.mit.edu
|
||||
* LCS.MIT.EDU kerberos.lcs.mit.edu admin server
|
||||
*
|
||||
* This is a temporary hack to allow us to find the nearest system running
|
||||
* kerberos. In the long run, this functionality will be provided by a
|
||||
* nameserver.
|
||||
*/
|
||||
|
||||
krb_get_krbhst(h,r,n)
|
||||
char *h;
|
||||
char *r;
|
||||
int n;
|
||||
{
|
||||
FILE *cnffile;
|
||||
char tr[REALM_SZ];
|
||||
char linebuf[BUFSIZ];
|
||||
register int i;
|
||||
|
||||
if ((cnffile = fopen(KRB_CONF,"r")) == NULL) {
|
||||
if (n==1) {
|
||||
(void) strcpy(h,KRB_HOST);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
else
|
||||
return(KFAILURE);
|
||||
}
|
||||
if (fscanf(cnffile,"%s",tr) == EOF)
|
||||
return(KFAILURE);
|
||||
/* run through the file, looking for the nth server for this realm */
|
||||
for (i = 1; i <= n;) {
|
||||
if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
|
||||
(void) fclose(cnffile);
|
||||
return(KFAILURE);
|
||||
}
|
||||
if (sscanf(linebuf, "%s %s", tr, h) != 2)
|
||||
continue;
|
||||
if (!strcmp(tr,r))
|
||||
i++;
|
||||
}
|
||||
(void) fclose(cnffile);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_krbrlm.c,v 4.8 89/01/22 20:02:54 rfrench Exp $
|
||||
* $Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: get_krbrlm.c,v 1.2 1994/07/19 19:25:19 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* krb_get_lrealm takes a pointer to a string, and a number, n. It fills
|
||||
* in the string, r, with the name of the nth realm specified on the
|
||||
* first line of the kerberos config file (KRB_CONF, defined in "krb.h").
|
||||
* It returns 0 (KSUCCESS) on success, and KFAILURE on failure. If the
|
||||
* config file does not exist, and if n=1, a successful return will occur
|
||||
* with r = KRB_REALM (also defined in "krb.h").
|
||||
*
|
||||
* NOTE: for archaic & compatibility reasons, this routine will only return
|
||||
* valid results when n = 1.
|
||||
*
|
||||
* For the format of the KRB_CONF file, see comments describing the routine
|
||||
* krb_get_krbhst().
|
||||
*/
|
||||
|
||||
krb_get_lrealm(r,n)
|
||||
char *r;
|
||||
int n;
|
||||
{
|
||||
FILE *cnffile, *fopen();
|
||||
|
||||
if (n > 1)
|
||||
return(KFAILURE); /* Temporary restriction */
|
||||
|
||||
if ((cnffile = fopen(KRB_CONF, "r")) == NULL) {
|
||||
if (n == 1) {
|
||||
(void) strcpy(r, KRB_REALM);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
else
|
||||
return(KFAILURE);
|
||||
}
|
||||
|
||||
if (fscanf(cnffile,"%s",r) != 1) {
|
||||
(void) fclose(cnffile);
|
||||
return(KFAILURE);
|
||||
}
|
||||
(void) fclose(cnffile);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_phost.c,v 4.6 89/01/23 09:25:40 jtkohl Exp $
|
||||
* $Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: get_phost.c,v 1.2 1994/07/19 19:25:20 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
|
||||
char *index();
|
||||
|
||||
/*
|
||||
* This routine takes an alias for a host name and returns the first
|
||||
* field, lower case, of its domain name. For example, if "menel" is
|
||||
* an alias for host officially named "menelaus" (in /etc/hosts), for
|
||||
* the host whose official name is "MENELAUS.MIT.EDU", the name "menelaus"
|
||||
* is returned.
|
||||
*
|
||||
* This is done for historical Athena reasons: the Kerberos name of
|
||||
* rcmd servers (rlogin, rsh, rcp) is of the form "rcmd.host@realm"
|
||||
* where "host"is the lowercase for of the host name ("menelaus").
|
||||
* This should go away: the instance should be the domain name
|
||||
* (MENELAUS.MIT.EDU). But for now we need this routine...
|
||||
*
|
||||
* A pointer to the name is returned, if found, otherwise a pointer
|
||||
* to the original "alias" argument is returned.
|
||||
*/
|
||||
|
||||
char * krb_get_phost(alias)
|
||||
char *alias;
|
||||
{
|
||||
struct hostent *h;
|
||||
char *phost = alias;
|
||||
if ((h=gethostbyname(alias)) != (struct hostent *)NULL ) {
|
||||
char *p = index( h->h_name, '.' );
|
||||
if (p)
|
||||
*p = NULL;
|
||||
p = phost = h->h_name;
|
||||
do {
|
||||
if (isupper(*p)) *p=tolower(*p);
|
||||
} while (*p++);
|
||||
}
|
||||
return(phost);
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_pw_tkt.c,v 4.6 89/01/13 18:19:11 steiner Exp $
|
||||
* $Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: get_pw_tkt.c,v 1.2 1994/07/19 19:25:23 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
|
||||
#include <krb.h>
|
||||
|
||||
/*
|
||||
* Get a ticket for the password-changing server ("changepw.KRB_MASTER").
|
||||
*
|
||||
* Given the name, instance, realm, and current password of the
|
||||
* principal for which the user wants a password-changing-ticket,
|
||||
* return either:
|
||||
*
|
||||
* GT_PW_BADPW if current password was wrong,
|
||||
* GT_PW_NULL if principal had a NULL password,
|
||||
* or the result of the krb_get_pw_in_tkt() call.
|
||||
*
|
||||
* First, try to get a ticket for "user.instance@realm" to use the
|
||||
* "changepw.KRB_MASTER" server (KRB_MASTER is defined in "krb.h").
|
||||
* The requested lifetime for the ticket is "1", and the current
|
||||
* password is the "cpw" argument given.
|
||||
*
|
||||
* If the password was bad, give up.
|
||||
*
|
||||
* If the principal had a NULL password in the Kerberos database
|
||||
* (indicating that the principal is known to Kerberos, but hasn't
|
||||
* got a password yet), try instead to get a ticket for the principal
|
||||
* "default.changepw@realm" to use the "changepw.KRB_MASTER" server.
|
||||
* Use the password "changepwkrb" instead of "cpw". Return GT_PW_NULL
|
||||
* if all goes well, otherwise the error.
|
||||
*
|
||||
* If this routine succeeds, a ticket and session key for either the
|
||||
* principal "user.instance@realm" or "default.changepw@realm" to use
|
||||
* the password-changing server will be in the user's ticket file.
|
||||
*/
|
||||
|
||||
get_pw_tkt(user,instance,realm,cpw)
|
||||
char *user;
|
||||
char *instance;
|
||||
char *realm;
|
||||
char *cpw;
|
||||
{
|
||||
int kerror;
|
||||
|
||||
kerror = krb_get_pw_in_tkt(user, instance, realm, "changepw",
|
||||
KRB_MASTER, 1, cpw);
|
||||
|
||||
if (kerror == INTK_BADPW)
|
||||
return(GT_PW_BADPW);
|
||||
|
||||
if (kerror == KDC_NULL_KEY) {
|
||||
kerror = krb_get_pw_in_tkt("default","changepw",realm,"changepw",
|
||||
KRB_MASTER,1,"changepwkrb");
|
||||
if (kerror)
|
||||
return(kerror);
|
||||
return(GT_PW_NULL);
|
||||
}
|
||||
|
||||
return(kerror);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_request.c,v 4.7 88/12/01 14:00:11 jtkohl Exp $
|
||||
* $Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: get_request.c,v 1.2 1994/07/19 19:25:24 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
|
||||
/*
|
||||
* This procedure is obsolete. It is used in the kerberos_slave
|
||||
* code for Version 3 tickets.
|
||||
*
|
||||
* This procedure sets s_name, and instance to point to
|
||||
* the corresponding fields from tne nth request in the packet.
|
||||
* it returns the lifetime requested. Garbage will be returned
|
||||
* if there are less than n requests in the packet.
|
||||
*/
|
||||
|
||||
get_request(pkt, n, s_name, instance)
|
||||
KTEXT pkt; /* The packet itself */
|
||||
int n; /* Which request do we want */
|
||||
char **s_name; /* Service name to be filled in */
|
||||
char **instance; /* Instance name to be filled in */
|
||||
{
|
||||
/* Go to the beginning of the request list */
|
||||
char *ptr = (char *) pkt_a_realm(pkt) + 6 +
|
||||
strlen((char *)pkt_a_realm(pkt));
|
||||
|
||||
/* Read requests until we hit the right one */
|
||||
while (n-- > 1) {
|
||||
ptr++;
|
||||
ptr += 1 + strlen(ptr);
|
||||
ptr += 1 + strlen(ptr);
|
||||
}
|
||||
|
||||
/* Set the arguments to point to the right place */
|
||||
*s_name = 1 + ptr;
|
||||
*instance = 2 + ptr + strlen(*s_name);
|
||||
|
||||
/* Return the requested lifetime */
|
||||
return((int) *ptr);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_svc_in_tkt.c,v 4.9 89/07/18 16:33:34 jtkohl Exp $
|
||||
* $Id: get_svc_in_tkt.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: get_svc_in_tkt.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file contains two routines: srvtab_to_key(), which gets
|
||||
* a server's key from a srvtab file, and krb_get_svc_in_tkt() which
|
||||
* gets an initial ticket for a server.
|
||||
*/
|
||||
|
||||
/*
|
||||
* srvtab_to_key(): given a "srvtab" file (where the keys for the
|
||||
* service on a host are stored), return the private key of the
|
||||
* given service (user.instance@realm).
|
||||
*
|
||||
* srvtab_to_key() passes its arguments on to read_service_key(),
|
||||
* plus one additional argument, the key version number.
|
||||
* (Currently, the key version number is always 0; this value
|
||||
* is treated as a wildcard by read_service_key().)
|
||||
*
|
||||
* If the "srvtab" argument is null, KEYFILE (defined in "krb.h")
|
||||
* is passed in its place.
|
||||
*
|
||||
* It returns the return value of the read_service_key() call.
|
||||
* The service key is placed in "key".
|
||||
*/
|
||||
|
||||
static int srvtab_to_key(user, instance, realm, srvtab, key)
|
||||
char *user, *instance, *realm, *srvtab;
|
||||
C_Block key;
|
||||
{
|
||||
if (!srvtab)
|
||||
srvtab = KEYFILE;
|
||||
|
||||
return(read_service_key(user, instance, realm, 0, srvtab,
|
||||
(char *)key));
|
||||
}
|
||||
|
||||
/*
|
||||
* krb_get_svc_in_tkt() passes its arguments on to krb_get_in_tkt(),
|
||||
* plus two additional arguments: a pointer to the srvtab_to_key()
|
||||
* function to be used to get the key from the key file and a NULL
|
||||
* for the decryption procedure indicating that krb_get_in_tkt should
|
||||
* use the default method of decrypting the response from the KDC.
|
||||
*
|
||||
* It returns the return value of the krb_get_in_tkt() call.
|
||||
*/
|
||||
|
||||
krb_get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
|
||||
char *user, *instance, *realm, *service, *sinstance;
|
||||
int life;
|
||||
char *srvtab;
|
||||
{
|
||||
return(krb_get_in_tkt(user, instance, realm, service, sinstance,
|
||||
life, srvtab_to_key, NULL, srvtab));
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_tf_fullname.c,v 4.3 90/03/10 22:40:20 jon Exp $
|
||||
* $Id: get_tf_fullname.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: get_tf_fullname.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <strings.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* This file contains a routine to extract the fullname of a user
|
||||
* from the ticket file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* krb_get_tf_fullname() takes four arguments: the name of the
|
||||
* ticket file, and variables for name, instance, and realm to be
|
||||
* returned in. Since the realm of a ticket file is not really fully
|
||||
* supported, the realm used will be that of the the first ticket in
|
||||
* the file as this is the one that was obtained with a password by
|
||||
* krb_get_in_tkt().
|
||||
*/
|
||||
|
||||
krb_get_tf_fullname(ticket_file, name, instance, realm)
|
||||
char *ticket_file;
|
||||
char *name;
|
||||
char *instance;
|
||||
char *realm;
|
||||
{
|
||||
int tf_status;
|
||||
CREDENTIALS c;
|
||||
|
||||
if ((tf_status = tf_init(ticket_file, R_TKT_FIL)) != KSUCCESS)
|
||||
return(tf_status);
|
||||
|
||||
if (((tf_status = tf_get_pname(c.pname)) != KSUCCESS) ||
|
||||
((tf_status = tf_get_pinst(c.pinst)) != KSUCCESS))
|
||||
return (tf_status);
|
||||
|
||||
if (name)
|
||||
strcpy(name, c.pname);
|
||||
if (instance)
|
||||
strcpy(instance, c.pinst);
|
||||
if ((tf_status = tf_get_cred(&c)) == KSUCCESS) {
|
||||
if (realm)
|
||||
strcpy(realm, c.realm);
|
||||
}
|
||||
else {
|
||||
if (tf_status == EOF)
|
||||
return(KFAILURE);
|
||||
else
|
||||
return(tf_status);
|
||||
}
|
||||
(void) tf_close();
|
||||
|
||||
return(tf_status);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: get_tf_realm.c,v 4.2 90/01/02 13:40:19 jtkohl Exp $
|
||||
* $Id: get_tf_realm.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: get_tf_realm.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This file contains a routine to extract the realm of a kerberos
|
||||
* ticket file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* krb_get_tf_realm() takes two arguments: the name of a ticket
|
||||
* and a variable to store the name of the realm in.
|
||||
*
|
||||
*/
|
||||
|
||||
krb_get_tf_realm(ticket_file, realm)
|
||||
char *ticket_file;
|
||||
char *realm;
|
||||
{
|
||||
return(krb_get_tf_fullname(ticket_file, 0, 0, realm));
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* routine to convert hostname into realm name.
|
||||
*
|
||||
* from: getrealm.c,v 4.6 90/01/02 13:35:56 jtkohl Exp $
|
||||
* $Id: getrealm.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: getrealm.c,v 1.1.1.1 1994/09/30 14:50:00 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <strings.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <krb.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
/* for Ultrix and friends ... */
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
/*
|
||||
* krb_realmofhost.
|
||||
* Given a fully-qualified domain-style primary host name,
|
||||
* return the name of the Kerberos realm for the host.
|
||||
* If the hostname contains no discernable domain, or an error occurs,
|
||||
* return the local realm name, as supplied by get_krbrlm().
|
||||
* If the hostname contains a domain, but no translation is found,
|
||||
* the hostname's domain is converted to upper-case and returned.
|
||||
*
|
||||
* The format of each line of the translation file is:
|
||||
* domain_name kerberos_realm
|
||||
* -or-
|
||||
* host_name kerberos_realm
|
||||
*
|
||||
* domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
|
||||
* host names should be in the usual form (e.g. FOO.BAR.BAZ)
|
||||
*/
|
||||
|
||||
static char ret_realm[REALM_SZ+1];
|
||||
|
||||
char *
|
||||
krb_realmofhost(host)
|
||||
char *host;
|
||||
{
|
||||
char *domain;
|
||||
FILE *trans_file;
|
||||
char trans_host[MAXHOSTNAMELEN+1];
|
||||
char trans_realm[REALM_SZ+1];
|
||||
int retval;
|
||||
|
||||
domain = index(host, '.');
|
||||
|
||||
/* prepare default */
|
||||
if (domain) {
|
||||
char *cp;
|
||||
|
||||
strncpy(ret_realm, &domain[1], REALM_SZ);
|
||||
ret_realm[REALM_SZ] = '\0';
|
||||
/* Upper-case realm */
|
||||
for (cp = ret_realm; *cp; cp++)
|
||||
if (islower(*cp))
|
||||
*cp = toupper(*cp);
|
||||
} else {
|
||||
krb_get_lrealm(ret_realm, 1);
|
||||
}
|
||||
|
||||
if ((trans_file = fopen(KRB_RLM_TRANS, "r")) == (FILE *) 0) {
|
||||
/* krb_errno = KRB_NO_TRANS */
|
||||
return(ret_realm);
|
||||
}
|
||||
while (1) {
|
||||
if ((retval = fscanf(trans_file, "%s %s",
|
||||
trans_host, trans_realm)) != 2) {
|
||||
if (retval == EOF) {
|
||||
fclose(trans_file);
|
||||
return(ret_realm);
|
||||
}
|
||||
continue; /* ignore broken lines */
|
||||
}
|
||||
trans_host[MAXHOSTNAMELEN] = '\0';
|
||||
trans_realm[REALM_SZ] = '\0';
|
||||
if (!strcasecmp(trans_host, host)) {
|
||||
/* exact match of hostname, so return the realm */
|
||||
(void) strcpy(ret_realm, trans_realm);
|
||||
fclose(trans_file);
|
||||
return(ret_realm);
|
||||
}
|
||||
if ((trans_host[0] == '.') && domain) {
|
||||
/* this is a domain match */
|
||||
if (!strcasecmp(trans_host, domain)) {
|
||||
/* domain match, save for later */
|
||||
(void) strcpy(ret_realm, trans_realm);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* form: getst.c,v 4.5 88/11/15 16:31:39 jtkohl Exp $
|
||||
* $Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: getst.c,v 1.2 1994/07/19 19:25:33 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
/*
|
||||
* getst() takes a file descriptor, a string and a count. It reads
|
||||
* from the file until either it has read "count" characters, or until
|
||||
* it reads a null byte. When finished, what has been read exists in
|
||||
* the given string "s". If "count" characters were actually read, the
|
||||
* last is changed to a null, so the returned string is always null-
|
||||
* terminated. getst() returns the number of characters read, including
|
||||
* the null terminator.
|
||||
*/
|
||||
|
||||
getst(fd, s, n)
|
||||
int fd;
|
||||
register char *s;
|
||||
{
|
||||
register count = n;
|
||||
while (read(fd, s, 1) > 0 && --count)
|
||||
if (*s++ == '\0')
|
||||
return (n - count);
|
||||
*s = '\0';
|
||||
return (n - count);
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: kt.c,v 4.9 89/10/25 19:03:35 qjb Exp $
|
||||
* $Id: in_tkt.c,v 1.1.1.1 1994/09/30 14:50:01 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: in_tkt.c,v 1.1.1.1 1994/09/30 14:50:01 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef TKT_SHMEM
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
extern int krb_debug;
|
||||
|
||||
/*
|
||||
* in_tkt() is used to initialize the ticket store. It creates the
|
||||
* file to contain the tickets and writes the given user's name "pname"
|
||||
* and instance "pinst" in the file. in_tkt() returns KSUCCESS on
|
||||
* success, or KFAILURE if something goes wrong.
|
||||
*/
|
||||
|
||||
in_tkt(pname,pinst)
|
||||
char *pname;
|
||||
char *pinst;
|
||||
{
|
||||
int tktfile;
|
||||
uid_t me, metoo;
|
||||
struct stat buf;
|
||||
int count;
|
||||
char *file = TKT_FILE;
|
||||
int fd;
|
||||
register int i;
|
||||
char charbuf[BUFSIZ];
|
||||
#ifdef TKT_SHMEM
|
||||
char shmidname[MAXPATHLEN];
|
||||
#endif /* TKT_SHMEM */
|
||||
|
||||
me = getuid ();
|
||||
metoo = geteuid();
|
||||
if (lstat(file,&buf) == 0) {
|
||||
if (buf.st_uid != me && me == 0) {
|
||||
unlink(file);
|
||||
} else {
|
||||
if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
|
||||
buf.st_mode & 077) {
|
||||
if (krb_debug)
|
||||
fprintf(stderr,"Error initializing %s",file);
|
||||
return(KFAILURE);
|
||||
}
|
||||
/* file already exists, and permissions appear ok, so nuke it */
|
||||
if ((fd = open(file, O_RDWR, 0)) < 0)
|
||||
goto out; /* can't zero it, but we can still try truncating it */
|
||||
|
||||
bzero(charbuf, sizeof(charbuf));
|
||||
|
||||
for (i = 0; i < buf.st_size; i += sizeof(charbuf))
|
||||
if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
|
||||
(void) fsync(fd);
|
||||
(void) close(fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
(void) fsync(fd);
|
||||
(void) close(fd);
|
||||
}
|
||||
}
|
||||
out:
|
||||
/* arrange so the file is owned by the ruid
|
||||
(swap real & effective uid if necessary).
|
||||
This isn't a security problem, since the ticket file, if it already
|
||||
exists, has the right uid (== ruid) and mode. */
|
||||
if (me != metoo) {
|
||||
if (setreuid(metoo, me) < 0) {
|
||||
/* can't switch??? barf! */
|
||||
if (krb_debug)
|
||||
perror("in_tkt: setreuid");
|
||||
return(KFAILURE);
|
||||
} else
|
||||
if (krb_debug)
|
||||
printf("swapped UID's %d and %d\n",metoo,me);
|
||||
}
|
||||
if ((tktfile = open(file,O_CREAT | O_TRUNC | O_WRONLY,0600)) < 0) {
|
||||
if (krb_debug)
|
||||
fprintf(stderr,"Error initializing %s",TKT_FILE);
|
||||
return(KFAILURE);
|
||||
}
|
||||
if (me != metoo) {
|
||||
if (setreuid(me, metoo) < 0) {
|
||||
/* can't switch??? barf! */
|
||||
if (krb_debug)
|
||||
perror("in_tkt: setreuid2");
|
||||
return(KFAILURE);
|
||||
} else
|
||||
if (krb_debug)
|
||||
printf("swapped UID's %d and %d\n",me,metoo);
|
||||
}
|
||||
if (lstat(file,&buf) < 0) {
|
||||
if (krb_debug)
|
||||
fprintf(stderr,"Error initializing %s",TKT_FILE);
|
||||
return(KFAILURE);
|
||||
}
|
||||
|
||||
if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
|
||||
buf.st_mode & 077) {
|
||||
if (krb_debug)
|
||||
fprintf(stderr,"Error initializing %s",TKT_FILE);
|
||||
return(KFAILURE);
|
||||
}
|
||||
|
||||
count = strlen(pname)+1;
|
||||
if (write(tktfile,pname,count) != count) {
|
||||
(void) close(tktfile);
|
||||
return(KFAILURE);
|
||||
}
|
||||
count = strlen(pinst)+1;
|
||||
if (write(tktfile,pinst,count) != count) {
|
||||
(void) close(tktfile);
|
||||
return(KFAILURE);
|
||||
}
|
||||
(void) close(tktfile);
|
||||
#ifdef TKT_SHMEM
|
||||
(void) strcpy(shmidname, file);
|
||||
(void) strcat(shmidname, ".shm");
|
||||
return(krb_shm_create(shmidname));
|
||||
#else /* !TKT_SHMEM */
|
||||
return(KSUCCESS);
|
||||
#endif /* TKT_SHMEM */
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: k_gethostname.c,v 4.1 88/12/01 14:04:42 jtkohl Exp $
|
||||
* $Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: k_gethostname.c,v 1.2 1994/07/19 19:25:36 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#ifndef PC
|
||||
#ifndef BSD42
|
||||
/* teach me how to k_gethostname for your system here */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PC
|
||||
#include <stdio.h>
|
||||
typedef long in_name;
|
||||
#include "custom.h" /* where is this file? */
|
||||
extern get_custom();
|
||||
#define LEN 64 /* just a guess */
|
||||
#endif /* PC */
|
||||
|
||||
/*
|
||||
* Return the local host's name in "name", up to "namelen" characters.
|
||||
* "name" will be null-terminated if "namelen" is big enough.
|
||||
* The return code is 0 on success, -1 on failure. (The calling
|
||||
* interface is identical to gethostname(2).)
|
||||
*
|
||||
* Currently defined for BSD 4.2 and PC. The BSD version just calls
|
||||
* gethostname(); the PC code was taken from "kinit.c", and may or may
|
||||
* not work.
|
||||
*/
|
||||
|
||||
k_gethostname(name, namelen)
|
||||
char *name;
|
||||
{
|
||||
#ifdef BSD42
|
||||
return gethostname(name, namelen);
|
||||
#endif
|
||||
|
||||
#ifdef PC
|
||||
char buf[LEN];
|
||||
char b1, b2, b3, b4;
|
||||
register char *ptr;
|
||||
|
||||
get_custom(); /* should check for errors,
|
||||
* return -1 on failure */
|
||||
ptr = (char *) &(custom.c_me);
|
||||
b1 = *ptr++;
|
||||
b2 = *ptr++;
|
||||
b3 = *ptr++;
|
||||
b4 = *ptr;
|
||||
(void) sprintf(buf,"PC address %d.%d.%d.%d",b1,b2,b3,b4);
|
||||
if (strlen(buf) > namelen)
|
||||
fprintf(stderr, "gethostname: namelen too small; truncating");
|
||||
strnpcy(name, buf, namelen);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: klog.c,v 4.6 88/12/01 14:06:05 jtkohl Exp $
|
||||
* $Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: klog.c,v 1.2 1994/07/19 19:25:37 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <krb.h>
|
||||
#include <klog.h>
|
||||
|
||||
static char *log_name = KRBLOG;
|
||||
static int is_open;
|
||||
static char logtxt[1000];
|
||||
|
||||
/*
|
||||
* This file contains two logging routines: kset_logfile()
|
||||
* to determine the file to which log entries should be written;
|
||||
* and klog() to write log entries to the file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* klog() is used to add entries to the logfile (see kset_logfile()
|
||||
* below). Note that it is probably not portable since it makes
|
||||
* assumptions about what the compiler will do when it is called
|
||||
* with less than the correct number of arguments which is the
|
||||
* way it is usually called.
|
||||
*
|
||||
* The log entry consists of a timestamp and the given arguments
|
||||
* printed according to the given "format" string.
|
||||
*
|
||||
* The log file is opened and closed for each log entry.
|
||||
*
|
||||
* If the given log type "type" is unknown, or if the log file
|
||||
* cannot be opened, no entry is made to the log file.
|
||||
*
|
||||
* The return value is always a pointer to the formatted log
|
||||
* text string "logtxt".
|
||||
*/
|
||||
|
||||
char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
|
||||
int type;
|
||||
char *format;
|
||||
int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
|
||||
{
|
||||
FILE *logfile, *fopen();
|
||||
long time(),now;
|
||||
char *month_sname();
|
||||
struct tm *tm;
|
||||
static int logtype_array[NLOGTYPE] = {0,0};
|
||||
static int array_initialized;
|
||||
|
||||
if (!(array_initialized++)) {
|
||||
logtype_array[L_NET_ERR] = 1;
|
||||
logtype_array[L_KRB_PERR] = 1;
|
||||
logtype_array[L_KRB_PWARN] = 1;
|
||||
logtype_array[L_APPL_REQ] = 1;
|
||||
logtype_array[L_INI_REQ] = 1;
|
||||
logtype_array[L_DEATH_REQ] = 1;
|
||||
logtype_array[L_NTGT_INTK] = 1;
|
||||
logtype_array[L_ERR_SEXP] = 1;
|
||||
logtype_array[L_ERR_MKV] = 1;
|
||||
logtype_array[L_ERR_NKY] = 1;
|
||||
logtype_array[L_ERR_NUN] = 1;
|
||||
logtype_array[L_ERR_UNK] = 1;
|
||||
}
|
||||
|
||||
(void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
|
||||
|
||||
if (!logtype_array[type])
|
||||
return(logtxt);
|
||||
|
||||
if ((logfile = fopen(log_name,"a")) == NULL)
|
||||
return(logtxt);
|
||||
|
||||
(void) time(&now);
|
||||
tm = localtime(&now);
|
||||
|
||||
fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
|
||||
month_sname(tm->tm_mon + 1),tm->tm_year,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
fprintf(logfile,"%s\n",logtxt);
|
||||
(void) fclose(logfile);
|
||||
return(logtxt);
|
||||
}
|
||||
|
||||
/*
|
||||
* kset_logfile() changes the name of the file to which
|
||||
* messages are logged. If kset_logfile() is not called,
|
||||
* the logfile defaults to KRBLOG, defined in "krb.h".
|
||||
*/
|
||||
|
||||
kset_logfile(filename)
|
||||
char *filename;
|
||||
{
|
||||
log_name = filename;
|
||||
is_open = 0;
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: kname_parse.c,v 4.4 88/12/01 14:07:29 jtkohl Exp $
|
||||
* $Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: kname_parse.c,v 1.2 1994/07/19 19:25:39 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* max size of full name */
|
||||
#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
|
||||
|
||||
#define NAME 0 /* which field are we in? */
|
||||
#define INST 1
|
||||
#define REALM 2
|
||||
|
||||
extern char *krb_err_txt[];
|
||||
|
||||
/*
|
||||
* This file contains four routines for handling Kerberos names.
|
||||
*
|
||||
* kname_parse() breaks a Kerberos name into its name, instance,
|
||||
* and realm components.
|
||||
*
|
||||
* k_isname(), k_isinst(), and k_isrealm() check a given string to see if
|
||||
* it's a syntactically legitimate respective part of a Kerberos name,
|
||||
* returning 1 if it is, 0 if it isn't.
|
||||
*
|
||||
* Definition of "syntactically legitimate" names is according to
|
||||
* the Project Athena Technical Plan Section E.2.1, page 7 "Specifying
|
||||
* names", version dated 21 Dec 1987.
|
||||
* /
|
||||
|
||||
/*
|
||||
* kname_parse() takes a Kerberos name "fullname" of the form:
|
||||
*
|
||||
* username[.instance][@realm]
|
||||
*
|
||||
* and returns the three components ("name", "instance", and "realm"
|
||||
* in the example above) in the given arguments "np", "ip", and "rp".
|
||||
*
|
||||
* If successful, it returns KSUCCESS. If there was an error,
|
||||
* KNAME_FMT is returned.
|
||||
*/
|
||||
|
||||
kname_parse(np, ip, rp, fullname)
|
||||
char *np, *ip, *rp, *fullname;
|
||||
{
|
||||
static char buf[FULL_SZ];
|
||||
char *rnext, *wnext; /* next char to read, write */
|
||||
register char c;
|
||||
int backslash;
|
||||
int field;
|
||||
|
||||
backslash = 0;
|
||||
rnext = buf;
|
||||
wnext = np;
|
||||
field = NAME;
|
||||
|
||||
if (strlen(fullname) > FULL_SZ)
|
||||
return KNAME_FMT;
|
||||
(void) strcpy(buf, fullname);
|
||||
|
||||
while (c = *rnext++) {
|
||||
if (backslash) {
|
||||
*wnext++ = c;
|
||||
backslash = 0;
|
||||
continue;
|
||||
}
|
||||
switch (c) {
|
||||
case '\\':
|
||||
backslash++;
|
||||
break;
|
||||
case '.':
|
||||
switch (field) {
|
||||
case NAME:
|
||||
if (wnext == np)
|
||||
return KNAME_FMT;
|
||||
*wnext = '\0';
|
||||
field = INST;
|
||||
wnext = ip;
|
||||
break;
|
||||
case INST:
|
||||
return KNAME_FMT;
|
||||
/* break; */
|
||||
case REALM:
|
||||
*wnext++ = c;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown field value\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case '@':
|
||||
switch (field) {
|
||||
case NAME:
|
||||
if (wnext == np)
|
||||
return KNAME_FMT;
|
||||
*ip = '\0';
|
||||
/* fall through */
|
||||
case INST:
|
||||
*wnext = '\0';
|
||||
field = REALM;
|
||||
wnext = rp;
|
||||
break;
|
||||
case REALM:
|
||||
return KNAME_FMT;
|
||||
default:
|
||||
fprintf(stderr, "unknown field value\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*wnext++ = c;
|
||||
}
|
||||
}
|
||||
*wnext = '\0';
|
||||
if ((strlen(np) > ANAME_SZ - 1) ||
|
||||
(strlen(ip) > INST_SZ - 1) ||
|
||||
(strlen(rp) > REALM_SZ - 1))
|
||||
return KNAME_FMT;
|
||||
return KSUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* k_isname() returns 1 if the given name is a syntactically legitimate
|
||||
* Kerberos name; returns 0 if it's not.
|
||||
*/
|
||||
|
||||
k_isname(s)
|
||||
char *s;
|
||||
{
|
||||
register char c;
|
||||
int backslash = 0;
|
||||
|
||||
if (!*s)
|
||||
return 0;
|
||||
if (strlen(s) > ANAME_SZ - 1)
|
||||
return 0;
|
||||
while(c = *s++) {
|
||||
if (backslash) {
|
||||
backslash = 0;
|
||||
continue;
|
||||
}
|
||||
switch(c) {
|
||||
case '\\':
|
||||
backslash = 1;
|
||||
break;
|
||||
case '.':
|
||||
return 0;
|
||||
/* break; */
|
||||
case '@':
|
||||
return 0;
|
||||
/* break; */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* k_isinst() returns 1 if the given name is a syntactically legitimate
|
||||
* Kerberos instance; returns 0 if it's not.
|
||||
*/
|
||||
|
||||
k_isinst(s)
|
||||
char *s;
|
||||
{
|
||||
register char c;
|
||||
int backslash = 0;
|
||||
|
||||
if (strlen(s) > INST_SZ - 1)
|
||||
return 0;
|
||||
while(c = *s++) {
|
||||
if (backslash) {
|
||||
backslash = 0;
|
||||
continue;
|
||||
}
|
||||
switch(c) {
|
||||
case '\\':
|
||||
backslash = 1;
|
||||
break;
|
||||
case '.':
|
||||
return 0;
|
||||
/* break; */
|
||||
case '@':
|
||||
return 0;
|
||||
/* break; */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* k_isrealm() returns 1 if the given name is a syntactically legitimate
|
||||
* Kerberos realm; returns 0 if it's not.
|
||||
*/
|
||||
|
||||
k_isrealm(s)
|
||||
char *s;
|
||||
{
|
||||
register char c;
|
||||
int backslash = 0;
|
||||
|
||||
if (!*s)
|
||||
return 0;
|
||||
if (strlen(s) > REALM_SZ - 1)
|
||||
return 0;
|
||||
while(c = *s++) {
|
||||
if (backslash) {
|
||||
backslash = 0;
|
||||
continue;
|
||||
}
|
||||
switch(c) {
|
||||
case '\\':
|
||||
backslash = 1;
|
||||
break;
|
||||
case '@':
|
||||
return 0;
|
||||
/* break; */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: kntoln.c,v 4.7 89/01/23 09:25:15 jtkohl Exp $
|
||||
* $Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: kntoln.c,v 1.2 1994/07/19 19:25:40 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* krb_kntoln converts an auth name into a local name by looking up
|
||||
* the auth name in the /etc/aname file. The format of the aname
|
||||
* file is:
|
||||
*
|
||||
* +-----+-----+-----+-----+------+----------+-------+-------+
|
||||
* | anl | inl | rll | lnl | name | instance | realm | lname |
|
||||
* +-----+-----+-----+-----+------+----------+-------+-------+
|
||||
* | 1by | 1by | 1by | 1by | name | instance | realm | lname |
|
||||
* +-----+-----+-----+-----+------+----------+-------+-------+
|
||||
*
|
||||
* If the /etc/aname file can not be opened it will set the
|
||||
* local name to the auth name. Thus, in this case it performs as
|
||||
* the identity function.
|
||||
*
|
||||
* The name instance and realm are passed to krb_kntoln through
|
||||
* the AUTH_DAT structure (ad).
|
||||
*
|
||||
* Now here's what it *really* does:
|
||||
*
|
||||
* Given a Kerberos name in an AUTH_DAT structure, check that the
|
||||
* instance is null, and that the realm is the same as the local
|
||||
* realm, and return the principal's name in "lname". Return
|
||||
* KSUCCESS if all goes well, otherwise KFAILURE.
|
||||
*/
|
||||
|
||||
krb_kntoln(ad,lname)
|
||||
AUTH_DAT *ad;
|
||||
char *lname;
|
||||
{
|
||||
static char lrealm[REALM_SZ] = "";
|
||||
|
||||
if (!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE))
|
||||
return(KFAILURE);
|
||||
|
||||
if (strcmp(ad->pinst,""))
|
||||
return(KFAILURE);
|
||||
if (strcmp(ad->prealm,lrealm))
|
||||
return(KFAILURE);
|
||||
(void) strcpy(lname,ad->pname);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
@@ -1,763 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* Purpose:
|
||||
* This module was developed to parse the "~/.klogin" files for
|
||||
* Kerberos-authenticated rlogin/rcp/rsh services. However, it is
|
||||
* general purpose and can be used to parse any such parameter file.
|
||||
*
|
||||
* The parameter file should consist of one or more entries, with each
|
||||
* entry on a separate line and consisting of zero or more
|
||||
* "keyword=value" combinations. The keyword is case insensitive, but
|
||||
* the value is not. Any string may be enclosed in quotes, and
|
||||
* c-style "\" literals are supported. A comma may be used to
|
||||
* separate the k/v combinations, and multiple commas are ignored.
|
||||
* Whitespace (blank or tab) may be used freely and is ignored.
|
||||
*
|
||||
* Full error processing is available. When PS_BAD_KEYWORD or
|
||||
* PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg
|
||||
* contains a meaningful error message.
|
||||
*
|
||||
* Keywords and their default values are programmed by an external
|
||||
* table.
|
||||
*
|
||||
* Routines:
|
||||
* fGetParameterSet() parse one line of the parameter file
|
||||
* fGetKeywordValue() parse one "keyword=value" combo
|
||||
* fGetToken() parse one token
|
||||
*
|
||||
*
|
||||
* from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $
|
||||
* $Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: kparse.c,v 1.2 1994/07/19 19:25:42 g89r4222 Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <kparse.h>
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define void int
|
||||
|
||||
#define MAXKEY 80
|
||||
#define MAXVALUE 80
|
||||
|
||||
char *malloc();
|
||||
char *strcpy();
|
||||
|
||||
int LineNbr=1; /* current line nbr in parameter file */
|
||||
char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX,
|
||||
* or PS_BAD_KEYWORD is returned by
|
||||
* fGetKeywordValue or fGetParameterSet */
|
||||
|
||||
int fGetParameterSet( fp,parm,parmcount )
|
||||
FILE *fp;
|
||||
parmtable parm[];
|
||||
int parmcount;
|
||||
{
|
||||
int rc,i;
|
||||
char keyword[MAXKEY];
|
||||
char value[MAXVALUE];
|
||||
|
||||
while (TRUE) {
|
||||
rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE);
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case KV_EOF:
|
||||
return(PS_EOF);
|
||||
|
||||
case KV_EOL:
|
||||
return(PS_OKAY);
|
||||
|
||||
case KV_SYNTAX:
|
||||
return(PS_SYNTAX);
|
||||
|
||||
case KV_OKAY:
|
||||
/*
|
||||
* got a reasonable keyword/value pair. Search the
|
||||
* parameter table to see if we recognize the keyword; if
|
||||
* not, return an error. If we DO recognize it, make sure
|
||||
* it has not already been given. If not already given,
|
||||
* save the value.
|
||||
*/
|
||||
for (i=0; i<parmcount; i++) {
|
||||
if (strcmp(strutol(keyword),parm[i].keyword)==0) {
|
||||
if (parm[i].value) {
|
||||
sprintf(ErrorMsg,"duplicate keyword \"%s\" found",
|
||||
keyword);
|
||||
return(PS_BAD_KEYWORD);
|
||||
}
|
||||
parm[i].value = strsave( value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= parmcount) {
|
||||
sprintf(ErrorMsg, "unrecognized keyword \"%s\" found",
|
||||
keyword);
|
||||
return(PS_BAD_KEYWORD);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(ErrorMsg,
|
||||
"panic: bad return (%d) from fGetToken()",rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: ParmCompare
|
||||
*
|
||||
* Purpose:
|
||||
* ParmCompare checks a specified value for a particular keyword.
|
||||
* fails if keyword not found or keyword found but the value was
|
||||
* different. Like strcmp, ParmCompare returns 0 for a match found, -1
|
||||
* otherwise
|
||||
*/
|
||||
int ParmCompare( parm, parmcount, keyword, value )
|
||||
parmtable parm[];
|
||||
int parmcount;
|
||||
char *keyword;
|
||||
char *value;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<parmcount; i++) {
|
||||
if (strcmp(parm[i].keyword,keyword)==0) {
|
||||
if (parm[i].value) {
|
||||
return(strcmp(parm[i].value,value));
|
||||
} else {
|
||||
return(strcmp(parm[i].defvalue,value));
|
||||
}
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void FreeParameterSet(parm,parmcount)
|
||||
parmtable parm[];
|
||||
int parmcount;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<parmcount; i++) {
|
||||
if (parm[i].value) {
|
||||
free(parm[i].value);
|
||||
parm[i].value = (char *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fGetKeywordValue( fp, keyword, klen, value, vlen )
|
||||
FILE *fp;
|
||||
char *keyword;
|
||||
int klen;
|
||||
char *value;
|
||||
int vlen;
|
||||
{
|
||||
int rc;
|
||||
int gotit;
|
||||
|
||||
*keyword = *value = '\0'; /* preset strings to NULL */
|
||||
|
||||
/*
|
||||
* Looking for a keyword.
|
||||
* return an exception for EOF or BAD_QSTRING
|
||||
* ignore leading WHITEspace
|
||||
* ignore any number of leading commas
|
||||
* newline means we have all the parms for this
|
||||
* statement; give an indication that there is
|
||||
* nothing more on this line.
|
||||
* stop looking if we find QSTRING, STRING, or NUMBER
|
||||
* return syntax error for any other PUNKtuation
|
||||
*/
|
||||
gotit = FALSE;
|
||||
do {
|
||||
rc = fGetToken(fp,keyword,klen);
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case GTOK_WHITE:
|
||||
break;
|
||||
|
||||
case GTOK_EOF:
|
||||
return(KV_EOF);
|
||||
|
||||
case GTOK_BAD_QSTRING:
|
||||
sprintf(ErrorMsg,"unterminated string \"%s found",keyword);
|
||||
return(KV_SYNTAX);
|
||||
|
||||
case GTOK_PUNK:
|
||||
if (strcmp("\n",keyword)==0) {
|
||||
return(KV_EOL);
|
||||
} else if (strcmp(",",keyword)!=0) {
|
||||
sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword);
|
||||
}
|
||||
break;
|
||||
|
||||
case GTOK_STRING:
|
||||
case GTOK_QSTRING:
|
||||
case GTOK_NUMBER:
|
||||
gotit = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc);
|
||||
return(KV_SYNTAX);
|
||||
}
|
||||
|
||||
} while (!gotit);
|
||||
|
||||
/*
|
||||
* now we expect an equal sign.
|
||||
* skip any whitespace
|
||||
* stop looking if we find an equal sign
|
||||
* anything else causes a syntax error
|
||||
*/
|
||||
gotit = FALSE;
|
||||
do {
|
||||
rc = fGetToken(fp,value,vlen);
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case GTOK_WHITE:
|
||||
break;
|
||||
|
||||
case GTOK_BAD_QSTRING:
|
||||
sprintf(ErrorMsg,
|
||||
"expecting \'=\', found unterminated string \"%s",
|
||||
value);
|
||||
return(KV_SYNTAX);
|
||||
|
||||
case GTOK_PUNK:
|
||||
if (strcmp("=",value)==0) {
|
||||
gotit = TRUE;
|
||||
} else {
|
||||
if (strcmp("\n",value)==0) {
|
||||
sprintf(ErrorMsg,"expecting \"=\", found newline");
|
||||
fUngetChar('\n',fp);
|
||||
} else {
|
||||
sprintf(ErrorMsg,
|
||||
"expecting rvalue, found \'%s\'",keyword);
|
||||
}
|
||||
return(KV_SYNTAX);
|
||||
}
|
||||
break;
|
||||
|
||||
case GTOK_STRING:
|
||||
case GTOK_QSTRING:
|
||||
case GTOK_NUMBER:
|
||||
sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value);
|
||||
return(KV_SYNTAX);
|
||||
|
||||
case GTOK_EOF:
|
||||
sprintf(ErrorMsg,"expecting \'=\', found EOF");
|
||||
return(KV_SYNTAX);
|
||||
|
||||
default:
|
||||
sprintf(ErrorMsg,
|
||||
"panic: bad return (%d) from fGetToken()",rc);
|
||||
return(KV_SYNTAX);
|
||||
}
|
||||
|
||||
} while ( !gotit );
|
||||
|
||||
/*
|
||||
* got the keyword and equal sign, now get a value.
|
||||
* ignore any whitespace
|
||||
* any punctuation is a syntax error
|
||||
*/
|
||||
gotit = FALSE;
|
||||
do {
|
||||
rc = fGetToken(fp,value,vlen);
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case GTOK_WHITE:
|
||||
break;
|
||||
|
||||
case GTOK_EOF:
|
||||
sprintf(ErrorMsg,"expecting rvalue, found EOF");
|
||||
return(KV_SYNTAX);
|
||||
|
||||
case GTOK_BAD_QSTRING:
|
||||
sprintf(ErrorMsg,"unterminated quoted string \"%s",value);
|
||||
return(KV_SYNTAX);
|
||||
|
||||
case GTOK_PUNK:
|
||||
if (strcmp("\n",value)==0) {
|
||||
sprintf(ErrorMsg,"expecting rvalue, found newline");
|
||||
fUngetChar('\n',fp);
|
||||
} else {
|
||||
sprintf(ErrorMsg,
|
||||
"expecting rvalue, found \'%s\'",value);
|
||||
}
|
||||
return(KV_SYNTAX);
|
||||
break;
|
||||
|
||||
case GTOK_STRING:
|
||||
case GTOK_QSTRING:
|
||||
case GTOK_NUMBER:
|
||||
gotit = TRUE;
|
||||
return(KV_OKAY);
|
||||
|
||||
default:
|
||||
sprintf(ErrorMsg,
|
||||
"panic: bad return (%d) from fGetToken()",rc);
|
||||
return(KV_SYNTAX);
|
||||
}
|
||||
|
||||
} while ( !gotit );
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine Name: fGetToken
|
||||
*
|
||||
* Function: read the next token from the specified file.
|
||||
* A token is defined as a group of characters
|
||||
* terminated by a white space char (SPACE, CR,
|
||||
* LF, FF, TAB). The token returned is stripped of
|
||||
* both leading and trailing white space, and is
|
||||
* terminated by a NULL terminator. An alternate
|
||||
* definition of a token is a string enclosed in
|
||||
* single or double quotes.
|
||||
*
|
||||
* Explicit Parameters:
|
||||
* fp pointer to the input FILE
|
||||
* dest pointer to destination buffer
|
||||
* maxlen length of the destination buffer. The buffer
|
||||
* length INCLUDES the NULL terminator.
|
||||
*
|
||||
* Implicit Parameters: stderr where the "token too long" message goes
|
||||
*
|
||||
* External Procedures: fgetc
|
||||
*
|
||||
* Side Effects: None
|
||||
*
|
||||
* Return Value: A token classification value, as
|
||||
* defined in kparse.h. Note that the
|
||||
* classification for end of file is
|
||||
* always zero.
|
||||
*/
|
||||
int fGetToken(fp, dest, maxlen)
|
||||
FILE *fp;
|
||||
char *dest;
|
||||
int maxlen;
|
||||
{
|
||||
int ch='\0';
|
||||
int len=0;
|
||||
char *p = dest;
|
||||
int digits;
|
||||
|
||||
ch=fGetChar(fp);
|
||||
|
||||
/*
|
||||
* check for a quoted string. If found, take all characters
|
||||
* that fit until a closing quote is found. Note that this
|
||||
* algorithm will not behave well for a string which is too long.
|
||||
*/
|
||||
if (ISQUOTE(ch)) {
|
||||
int done = FALSE;
|
||||
do {
|
||||
ch = fGetChar(fp);
|
||||
done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF)
|
||||
||ISQUOTE(ch));
|
||||
if (ch=='\\')
|
||||
ch = fGetLiteral(fp);
|
||||
if (!done)
|
||||
*p++ = ch;
|
||||
else if ((ch!=EOF) && !ISQUOTE(ch))
|
||||
fUngetChar(ch,fp);
|
||||
} while (!done);
|
||||
*p = '\0';
|
||||
if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
|
||||
return(GTOK_QSTRING);
|
||||
}
|
||||
|
||||
/*
|
||||
* Not a quoted string. If its a token character (rules are
|
||||
* defined via the ISTOKENCHAR macro, in kparse.h) take it and all
|
||||
* token chars following it until we run out of space.
|
||||
*/
|
||||
digits=TRUE;
|
||||
if (ISTOKENCHAR(ch)) {
|
||||
while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
|
||||
if (!isdigit(ch)) digits=FALSE;
|
||||
*p++ = ch;
|
||||
len++;
|
||||
ch = fGetChar(fp);
|
||||
};
|
||||
*p = '\0';
|
||||
|
||||
if (ch!=EOF) {
|
||||
fUngetChar(ch,fp);
|
||||
}
|
||||
if (digits) {
|
||||
return(GTOK_NUMBER);
|
||||
} else {
|
||||
return(GTOK_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Neither a quoted string nor a token character. Return a string
|
||||
* with just that one character in it.
|
||||
*/
|
||||
if (ch==EOF) {
|
||||
return(GTOK_EOF);
|
||||
}
|
||||
if (!ISWHITESPACE(ch)) {
|
||||
*p++ = ch;
|
||||
*p='\0';
|
||||
} else {
|
||||
*p++ = ' '; /* white space is always the
|
||||
* blank character */
|
||||
*p='\0';
|
||||
/*
|
||||
* The character is a white space. Flush all additional white
|
||||
* space.
|
||||
*/
|
||||
while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
|
||||
;
|
||||
if (ch!=EOF) {
|
||||
fUngetChar(ch,fp);
|
||||
}
|
||||
return(GTOK_WHITE);
|
||||
}
|
||||
return(GTOK_PUNK);
|
||||
}
|
||||
|
||||
/*
|
||||
* fGetLiteral is called after we find a '\' in the input stream. A
|
||||
* string of numbers following the backslash are converted to the
|
||||
* appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
|
||||
* are all supported. If the char after the \ is not a number, we
|
||||
* special case certain values (\n, \f, \r, \b) or return a literal
|
||||
* otherwise (useful for \", for example).
|
||||
*/
|
||||
fGetLiteral(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
int ch;
|
||||
int n=0;
|
||||
int base;
|
||||
|
||||
ch = fGetChar(fp);
|
||||
|
||||
if (!isdigit(ch)) {
|
||||
switch (ch) {
|
||||
case 'n': return('\n');
|
||||
case 'f': return('\f');
|
||||
case 'r': return('\r');
|
||||
case 'b': return('\b');
|
||||
default: return(ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* got a number. might be decimal (no prefix), octal (prefix 0),
|
||||
* or hexadecimal (prefix 0x). Set the base appropriately.
|
||||
*/
|
||||
if (ch!='0') {
|
||||
base=10; /* its a decimal number */
|
||||
} else {
|
||||
/*
|
||||
* found a zero, its either hex or octal
|
||||
*/
|
||||
ch = fGetChar(fp);
|
||||
if ((ch!='x') && (ch!='X')) {
|
||||
base=010;
|
||||
} else {
|
||||
ch = fGetChar(fp);
|
||||
base=0x10;
|
||||
}
|
||||
}
|
||||
|
||||
switch (base) {
|
||||
|
||||
case 010: /* octal */
|
||||
while (ISOCTAL(ch)) {
|
||||
n = (n*base) + ch - '0';
|
||||
ch = fGetChar(fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 10: /* decimal */
|
||||
while (isdigit(ch)) {
|
||||
n = (n*base) + ch - '0';
|
||||
ch = fGetChar(fp);
|
||||
}
|
||||
break;
|
||||
case 0x10: /* hexadecimal */
|
||||
while (isxdigit(ch)) {
|
||||
if (isdigit(ch)) {
|
||||
n = (n*base) + ch - '0';
|
||||
} else {
|
||||
n = (n*base) + toupper(ch) - 'A' + 0xA ;
|
||||
}
|
||||
ch = fGetChar(fp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
fUngetChar(ch,fp);
|
||||
return(n);
|
||||
}
|
||||
|
||||
/*
|
||||
* exactly the same as ungetc(3) except that the line number of the
|
||||
* input file is maintained.
|
||||
*/
|
||||
fUngetChar(ch,fp)
|
||||
int ch;
|
||||
FILE *fp;
|
||||
{
|
||||
if (ch=='\n') LineNbr--;
|
||||
return(ungetc(ch,fp));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* exactly the same as fgetc(3) except that the line number of the
|
||||
* input file is maintained.
|
||||
*/
|
||||
fGetChar(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
int ch = fgetc(fp);
|
||||
if (ch=='\n') LineNbr++;
|
||||
return(ch);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Routine Name: strsave
|
||||
*
|
||||
* Function: return a pointer to a saved copy of the
|
||||
* input string. the copy will be allocated
|
||||
* as large as necessary.
|
||||
*
|
||||
* Explicit Parameters: pointer to string to save
|
||||
*
|
||||
* Implicit Parameters: None
|
||||
*
|
||||
* External Procedures: malloc,strcpy,strlen
|
||||
*
|
||||
* Side Effects: None
|
||||
*
|
||||
* Return Value: pointer to copied string
|
||||
*
|
||||
*/
|
||||
char * strsave(p)
|
||||
char *p;
|
||||
{
|
||||
return(strcpy(malloc(strlen(p)+1),p));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* strutol changes all characters in a string to lower case, in place.
|
||||
* the pointer to the beginning of the string is returned.
|
||||
*/
|
||||
|
||||
char * strutol( start )
|
||||
char *start;
|
||||
{
|
||||
char *q;
|
||||
for (q=start; *q; q++)
|
||||
if (isupper(*q))
|
||||
*q=tolower(*q);
|
||||
return(start);
|
||||
}
|
||||
|
||||
#ifdef GTOK_TEST /* mainline test routine for fGetToken() */
|
||||
|
||||
#define MAXTOKEN 100
|
||||
|
||||
char *pgm = "gettoken";
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *p;
|
||||
int type;
|
||||
FILE *fp;
|
||||
|
||||
if (--argc) {
|
||||
fp = fopen(*++argv,"ra");
|
||||
if (fp == (FILE *)NULL) {
|
||||
fprintf(stderr,"can\'t open \"%s\"\n",*argv);
|
||||
}
|
||||
} else
|
||||
fp = stdin;
|
||||
|
||||
p = malloc(MAXTOKEN);
|
||||
while (type = fGetToken(fp,p,MAXTOKEN)) {
|
||||
switch(type) {
|
||||
case GTOK_BAD_QSTRING:
|
||||
printf("BAD QSTRING!\t");
|
||||
break;
|
||||
case GTOK_EOF:
|
||||
printf("EOF!\t");
|
||||
break;
|
||||
case GTOK_QSTRING:
|
||||
printf("QSTRING\t");
|
||||
break;
|
||||
case GTOK_STRING:
|
||||
printf("STRING\t");
|
||||
break;
|
||||
case GTOK_NUMBER:
|
||||
printf("NUMBER\t");
|
||||
break;
|
||||
case GTOK_PUNK:
|
||||
printf("PUNK\t");
|
||||
break;
|
||||
case GTOK_WHITE:
|
||||
printf("WHITE\t");
|
||||
break;
|
||||
default:
|
||||
printf("HUH?\t");
|
||||
break;
|
||||
}
|
||||
if (*p=='\n')
|
||||
printf("\\n\n");
|
||||
else
|
||||
printf("%s\n",p);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KVTEST
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int rc,ch;
|
||||
FILE *fp;
|
||||
char key[MAXKEY],valu[MAXVALUE];
|
||||
char *filename;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"usage: test <filename>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!(fp=fopen(*++argv,"r"))) {
|
||||
fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
|
||||
exit(1);
|
||||
}
|
||||
filename = *argv;
|
||||
|
||||
while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case KV_EOL:
|
||||
printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
|
||||
break;
|
||||
|
||||
case KV_SYNTAX:
|
||||
printf("%s, line %d: syntax error: %s\n",
|
||||
filename,LineNbr,ErrorMsg);
|
||||
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
|
||||
break;
|
||||
|
||||
case KV_OKAY:
|
||||
printf("%s, line %d: okay, %s=\"%s\"\n",
|
||||
filename,LineNbr,key,valu);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("EOF");
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PSTEST
|
||||
|
||||
parmtable kparm[] = {
|
||||
/* keyword, default, found value */
|
||||
{ "user", "", (char *)NULL },
|
||||
{ "realm", "Athena", (char *)NULL },
|
||||
{ "instance", "", (char *)NULL }
|
||||
};
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int rc,i,ch;
|
||||
FILE *fp;
|
||||
char *filename;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"usage: test <filename>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!(fp=fopen(*++argv,"r"))) {
|
||||
fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
|
||||
exit(1);
|
||||
}
|
||||
filename = *argv;
|
||||
|
||||
while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case PS_BAD_KEYWORD:
|
||||
printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
|
||||
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
|
||||
break;
|
||||
|
||||
case PS_SYNTAX:
|
||||
printf("%s, line %d: syntax error: %s\n",
|
||||
filename,LineNbr,ErrorMsg);
|
||||
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
|
||||
break;
|
||||
|
||||
case PS_OKAY:
|
||||
printf("%s, line %d: valid parameter set found:\n",
|
||||
filename,LineNbr-1);
|
||||
for (i=0; i<PARMCOUNT(kparm); i++) {
|
||||
printf("\t%s = \"%s\"\n",kparm[i].keyword,
|
||||
(kparm[i].value ? kparm[i].value
|
||||
: kparm[i].defvalue));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("panic: bad return (%d) from fGetParameterSet\n",rc);
|
||||
break;
|
||||
}
|
||||
FreeParameterSet(kparm,PARMCOUNT(kparm));
|
||||
}
|
||||
printf("EOF");
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
@@ -1,462 +0,0 @@
|
||||
.\" $Source: /home/ncvs/src/eBones/man/krb.3,v $
|
||||
.\" $Author: rgrimes $
|
||||
.\" $Header: /home/ncvs/src/eBones/man/krb.3,v 1.1.1.1 1994/05/27 05:12:09 rgrimes Exp $
|
||||
.\" Copyright 1989 by the Massachusetts Institute of Technology.
|
||||
.\"
|
||||
.\" For copying and distribution information,
|
||||
.\" please see the file <mit-copyright.h>.
|
||||
.\"
|
||||
.TH KERBEROS 3 "Kerberos Version 4.0" "MIT Project Athena"
|
||||
.SH NAME
|
||||
krb_mk_req, krb_rd_req, krb_kntoln, krb_set_key, krb_get_cred,
|
||||
krb_mk_priv, krb_rd_priv, krb_mk_safe, krb_rd_safe, krb_mk_err,
|
||||
krb_rd_err, krb_ck_repl \- Kerberos authentication library
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.nj
|
||||
.ft B
|
||||
#include <kerberosIV/des.h>
|
||||
#include <kerberosIV/krb.h>
|
||||
.PP
|
||||
.ft B
|
||||
extern char *krb_err_txt[];
|
||||
.PP
|
||||
.ft B
|
||||
int krb_mk_req(authent,service,instance,realm,checksum)
|
||||
KTEXT authent;
|
||||
char *service;
|
||||
char *instance;
|
||||
char *realm;
|
||||
u_long checksum;
|
||||
.PP
|
||||
.ft B
|
||||
int krb_rd_req(authent,service,instance,from_addr,ad,fn)
|
||||
KTEXT authent;
|
||||
char *service;
|
||||
char *instance;
|
||||
u_long from_addr;
|
||||
AUTH_DAT *ad;
|
||||
char *fn;
|
||||
.PP
|
||||
.ft B
|
||||
int krb_kntoln(ad,lname)
|
||||
AUTH_DAT *ad;
|
||||
char *lname;
|
||||
.PP
|
||||
.ft B
|
||||
int krb_set_key(key,cvt)
|
||||
char *key;
|
||||
int cvt;
|
||||
.PP
|
||||
.ft B
|
||||
int krb_get_cred(service,instance,realm,c)
|
||||
char *service;
|
||||
char *instance;
|
||||
char *realm;
|
||||
CREDENTIALS *c;
|
||||
.PP
|
||||
.ft B
|
||||
long krb_mk_priv(in,out,in_length,schedule,key,sender,receiver)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
u_long in_length;
|
||||
des_cblock key;
|
||||
des_key_schedule schedule;
|
||||
struct sockaddr_in *sender;
|
||||
struct sockaddr_in *receiver;
|
||||
.PP
|
||||
.ft B
|
||||
long krb_rd_priv(in,in_length,schedule,key,sender,receiver,msg_data)
|
||||
u_char *in;
|
||||
u_long in_length;
|
||||
Key_schedule schedule;
|
||||
des_cblock key;
|
||||
struct sockaddr_in *sender;
|
||||
struct sockaddr_in *receiver;
|
||||
MSG_DAT *msg_data;
|
||||
.PP
|
||||
.ft B
|
||||
long krb_mk_safe(in,out,in_length,key,sender,receiver)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
u_long in_length;
|
||||
des_cblock key;
|
||||
struct sockaddr_in *sender;
|
||||
struct sockaddr_in *receiver;
|
||||
.PP
|
||||
.ft B
|
||||
long krb_rd_safe(in,length,key,sender,receiver,msg_data)
|
||||
u_char *in;
|
||||
u_long length;
|
||||
des_cblock key;
|
||||
struct sockaddr_in *sender;
|
||||
struct sockaddr_in *receiver;
|
||||
MSG_DAT *msg_data;
|
||||
.PP
|
||||
.ft B
|
||||
long krb_mk_err(out,code,string)
|
||||
u_char *out;
|
||||
long code;
|
||||
char *string;
|
||||
.PP
|
||||
.ft B
|
||||
long krb_rd_err(in,length,code,msg_data)
|
||||
u_char *in;
|
||||
u_long length;
|
||||
long code;
|
||||
MSG_DAT *msg_data;
|
||||
.fi
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
This library supports network authentication and various related
|
||||
operations. The library contains many routines beyond those described
|
||||
in this man page, but they are not intended to be used directly.
|
||||
Instead, they are called by the routines that are described, the
|
||||
authentication server and the login program.
|
||||
.PP
|
||||
.I krb_err_txt[]
|
||||
contains text string descriptions of various Kerberos error codes returned
|
||||
by some of the routines below.
|
||||
.PP
|
||||
.I krb_mk_req
|
||||
takes a pointer to a text structure in which an authenticator is to be
|
||||
built. It also takes the name, instance, and realm of the service to be
|
||||
used and an optional checksum. It is up to the application to decide
|
||||
how to generate the checksum.
|
||||
.I krb_mk_req
|
||||
then retrieves a ticket for the desired service and creates an
|
||||
authenticator. The authenticator is built in
|
||||
.I authent
|
||||
and is accessible
|
||||
to the calling procedure.
|
||||
.PP
|
||||
It is up to the application to get the authenticator to the service
|
||||
where it will be read by
|
||||
.I krb_rd_req.
|
||||
Unless an attacker posesses the session key contained in the ticket, it
|
||||
will be unable to modify the authenticator. Thus, the checksum can be
|
||||
used to verify the authenticity of the other data that will pass through
|
||||
a connection.
|
||||
.PP
|
||||
.I krb_rd_req
|
||||
takes an authenticator of type
|
||||
.B KTEXT,
|
||||
a service name, an instance, the address of the
|
||||
host originating the request, and a pointer to a structure of type
|
||||
.B AUTH_DAT
|
||||
which is filled in with information obtained from the authenticator.
|
||||
It also optionally takes the name of the file in which it will find the
|
||||
secret key(s) for the service.
|
||||
If the supplied
|
||||
.I instance
|
||||
contains "*", then the first service key with the same service name
|
||||
found in the service key file will be used, and the
|
||||
.I instance
|
||||
argument will be filled in with the chosen instance. This means that
|
||||
the caller must provide space for such an instance name.
|
||||
.PP
|
||||
It is used to find out information about the principal when a request
|
||||
has been made to a service. It is up to the application protocol to get
|
||||
the authenticator from the client to the service. The authenticator is
|
||||
then passed to
|
||||
.I krb_rd_req
|
||||
to extract the desired information.
|
||||
.PP
|
||||
.I krb_rd_req
|
||||
returns zero (RD_AP_OK) upon successful authentication. If a packet was
|
||||
forged, modified, or replayed, authentication will fail. If the
|
||||
authentication fails, a non-zero value is returned indicating the
|
||||
particular problem encountered. See
|
||||
.I krb.h
|
||||
for the list of error codes.
|
||||
.PP
|
||||
If the last argument is the null string (""), krb_rd_req will use the
|
||||
file /etc/kerberosIV/srvtab to find its keys. If the last argument is
|
||||
NULL, it will assume that the key has been set by
|
||||
.I krb_set_key
|
||||
and will not bother looking further.
|
||||
.PP
|
||||
.I krb_kntoln
|
||||
converts a Kerberos name to a local name. It takes a structure
|
||||
of type AUTH_DAT and uses the name and instance to look in the database
|
||||
/etc/kerberosIV/aname to find the corresponding local name. The local name is
|
||||
returned and can be used by an application to change uids, directories,
|
||||
or other parameters. It is not an integral part of Kerberos, but is
|
||||
instead provided to support the use of Kerberos in existing utilities.
|
||||
.PP
|
||||
.I krb_set_key
|
||||
takes as an argument a des key. It then creates
|
||||
a key schedule from it and saves the original key to be used as an
|
||||
initialization vector.
|
||||
It is used to set the server's key which
|
||||
must be used to decrypt tickets.
|
||||
.PP
|
||||
If called with a non-zero second argument,
|
||||
.I krb_set_key
|
||||
will first convert the input from a string of arbitrary length to a DES
|
||||
key by encrypting it with a one-way function.
|
||||
.PP
|
||||
In most cases it should not be necessary to call
|
||||
.I krb_set_key.
|
||||
The necessary keys will usually be obtained and set inside
|
||||
.I krb_rd_req. krb_set_key
|
||||
is provided for those applications that do not wish to place the
|
||||
application keys on disk.
|
||||
.PP
|
||||
.I krb_get_cred
|
||||
searches the caller's ticket file for a ticket for the given service, instance,
|
||||
and realm; and, if a ticket is found, fills in the given CREDENTIALS structure
|
||||
with the ticket information.
|
||||
.PP
|
||||
If the ticket was found,
|
||||
.I krb_get_cred
|
||||
returns GC_OK.
|
||||
If the ticket file can't be found, can't be read, doesn't belong to
|
||||
the user (other than root), isn't a regular file, or is in the wrong
|
||||
mode, the error GC_TKFIL is returned.
|
||||
.PP
|
||||
.I krb_mk_priv
|
||||
creates an encrypted, authenticated
|
||||
message from any arbitrary application data, pointed to by
|
||||
.I in
|
||||
and
|
||||
.I in_length
|
||||
bytes long.
|
||||
The private session key, pointed to by
|
||||
.I key
|
||||
and the key schedule,
|
||||
.I schedule,
|
||||
are used to encrypt the data and some header information using
|
||||
.I pcbc_encrypt.
|
||||
.I sender
|
||||
and
|
||||
.I receiver
|
||||
point to the Internet address of the two parties.
|
||||
In addition to providing privacy, this protocol message protects
|
||||
against modifications, insertions or replays. The encapsulated message and
|
||||
header are placed in the area pointed to by
|
||||
.I out
|
||||
and the routine returns the length of the output, or -1 indicating
|
||||
an error.
|
||||
.PP
|
||||
.I krb_rd_priv
|
||||
decrypts and authenticates a received
|
||||
.I krb_mk_priv
|
||||
message.
|
||||
.I in
|
||||
points to the beginning of the received message, whose length
|
||||
is specified in
|
||||
.I in_length.
|
||||
The private session key, pointed to by
|
||||
.I key,
|
||||
and the key schedule,
|
||||
.I schedule,
|
||||
are used to decrypt and verify the received message.
|
||||
.I msg_data
|
||||
is a pointer to a
|
||||
.I MSG_DAT
|
||||
struct, defined in
|
||||
.I krb.h.
|
||||
The routine fills in the
|
||||
.I app_data
|
||||
field with a pointer to the decrypted application data,
|
||||
.I app_length
|
||||
with the length of the
|
||||
.I app_data
|
||||
field,
|
||||
.I time_sec
|
||||
and
|
||||
.I time_5ms
|
||||
with the timestamps in the message, and
|
||||
.I swap
|
||||
with a 1 if the byte order of the receiver is different than that of
|
||||
the sender. (The application must still determine if it is appropriate
|
||||
to byte-swap application data; the Kerberos protocol fields are already taken
|
||||
care of). The
|
||||
.I hash
|
||||
field returns a value useful as input to the
|
||||
.I krb_ck_repl
|
||||
routine.
|
||||
|
||||
The routine returns zero if ok, or a Kerberos error code. Modified messages
|
||||
and old messages cause errors, but it is up to the caller to
|
||||
check the time sequence of messages, and to check against recently replayed
|
||||
messages using
|
||||
.I krb_ck_repl
|
||||
if so desired.
|
||||
.PP
|
||||
.I krb_mk_safe
|
||||
creates an authenticated, but unencrypted message from any arbitrary
|
||||
application data,
|
||||
pointed to by
|
||||
.I in
|
||||
and
|
||||
.I in_length
|
||||
bytes long.
|
||||
The private session key, pointed to by
|
||||
.I key,
|
||||
is used to seed the
|
||||
.I quad_cksum()
|
||||
checksum algorithm used as part of the authentication.
|
||||
.I sender
|
||||
and
|
||||
.I receiver
|
||||
point to the Internet address of the two parties.
|
||||
This message does not provide privacy, but does protect (via detection)
|
||||
against modifications, insertions or replays. The encapsulated message and
|
||||
header are placed in the area pointed to by
|
||||
.I out
|
||||
and the routine returns the length of the output, or -1 indicating
|
||||
an error.
|
||||
The authentication provided by this routine is not as strong as that
|
||||
provided by
|
||||
.I krb_mk_priv
|
||||
or by computing the checksum using
|
||||
.I cbc_cksum
|
||||
instead, both of which authenticate via DES.
|
||||
.PP
|
||||
|
||||
.I krb_rd_safe
|
||||
authenticates a received
|
||||
.I krb_mk_safe
|
||||
message.
|
||||
.I in
|
||||
points to the beginning of the received message, whose length
|
||||
is specified in
|
||||
.I in_length.
|
||||
The private session key, pointed to by
|
||||
.I key,
|
||||
is used to seed the quad_cksum() routine as part of the authentication.
|
||||
.I msg_data
|
||||
is a pointer to a
|
||||
.I MSG_DAT
|
||||
struct, defined in
|
||||
.I krb.h .
|
||||
The routine fills in these
|
||||
.I MSG_DAT
|
||||
fields:
|
||||
the
|
||||
.I app_data
|
||||
field with a pointer to the application data,
|
||||
.I app_length
|
||||
with the length of the
|
||||
.I app_data
|
||||
field,
|
||||
.I time_sec
|
||||
and
|
||||
.I time_5ms
|
||||
with the timestamps in the message, and
|
||||
.I swap
|
||||
with a 1 if the byte order of the receiver is different than that of
|
||||
the sender.
|
||||
(The application must still determine if it is appropriate
|
||||
to byte-swap application data; the Kerberos protocol fields are already taken
|
||||
care of). The
|
||||
.I hash
|
||||
field returns a value useful as input to the
|
||||
.I krb_ck_repl
|
||||
routine.
|
||||
|
||||
The routine returns zero if ok, or a Kerberos error code. Modified messages
|
||||
and old messages cause errors, but it is up to the caller to
|
||||
check the time sequence of messages, and to check against recently replayed
|
||||
messages using
|
||||
.I krb_ck_repl
|
||||
if so desired.
|
||||
.PP
|
||||
.I krb_mk_err
|
||||
constructs an application level error message that may be used along
|
||||
with
|
||||
.I krb_mk_priv
|
||||
or
|
||||
.I krb_mk_safe.
|
||||
.I out
|
||||
is a pointer to the output buffer,
|
||||
.I code
|
||||
is an application specific error code, and
|
||||
.I string
|
||||
is an application specific error string.
|
||||
|
||||
.PP
|
||||
.I krb_rd_err
|
||||
unpacks a received
|
||||
.I krb_mk_err
|
||||
message.
|
||||
.I in
|
||||
points to the beginning of the received message, whose length
|
||||
is specified in
|
||||
.I in_length.
|
||||
.I code
|
||||
is a pointer to a value to be filled in with the error
|
||||
value provided by the application.
|
||||
.I msg_data
|
||||
is a pointer to a
|
||||
.I MSG_DAT
|
||||
struct, defined in
|
||||
.I krb.h .
|
||||
The routine fills in these
|
||||
.I MSG_DAT
|
||||
fields: the
|
||||
.I app_data
|
||||
field with a pointer to the application error text,
|
||||
.I app_length
|
||||
with the length of the
|
||||
.I app_data
|
||||
field, and
|
||||
.I swap
|
||||
with a 1 if the byte order of the receiver is different than that of
|
||||
the sender. (The application must still determine if it is appropriate
|
||||
to byte-swap application data; the Kerberos protocol fields are already taken
|
||||
care of).
|
||||
|
||||
The routine returns zero if the error message has been successfully received,
|
||||
or a Kerberos error code.
|
||||
.PP
|
||||
The
|
||||
.I KTEXT
|
||||
structure is used to pass around text of varying lengths. It consists
|
||||
of a buffer for the data, and a length. krb_rd_req takes an argument of this
|
||||
type containing the authenticator, and krb_mk_req returns the
|
||||
authenticator in a structure of this type. KTEXT itself is really a
|
||||
pointer to the structure. The actual structure is of type KTEXT_ST.
|
||||
.PP
|
||||
The
|
||||
.I AUTH_DAT
|
||||
structure is filled in by krb_rd_req. It must be allocated before
|
||||
calling krb_rd_req, and a pointer to it is passed. The structure is
|
||||
filled in with data obtained from Kerberos.
|
||||
.I MSG_DAT
|
||||
structure is filled in by either krb_rd_priv, krb_rd_safe, or
|
||||
krb_rd_err. It must be allocated before the call and a pointer to it
|
||||
is passed. The structure is
|
||||
filled in with data obtained from Kerberos.
|
||||
.PP
|
||||
.SH FILES
|
||||
/usr/include/kerberosIV/krb.h
|
||||
.br
|
||||
/usr/lib/libkrb.a
|
||||
.br
|
||||
/usr/include/kerberosIV/des.h
|
||||
.br
|
||||
/usr/lib/libdes.a
|
||||
.br
|
||||
/etc/kerberosIV/aname
|
||||
.br
|
||||
/etc/kerberosIV/srvtab
|
||||
.br
|
||||
/tmp/tkt[uid]
|
||||
.SH "SEE ALSO"
|
||||
kerberos(1), des_crypt(3)
|
||||
.SH DIAGNOSTICS
|
||||
.SH BUGS
|
||||
The caller of
|
||||
.I krb_rd_req, krb_rd_priv, and krb_rd_safe
|
||||
must check time order and for replay attempts.
|
||||
.I krb_ck_repl
|
||||
is not implemented yet.
|
||||
.SH AUTHORS
|
||||
Clifford Neuman, MIT Project Athena
|
||||
.br
|
||||
Steve Miller, MIT Project Athena/Digital Equipment Corporation
|
||||
.SH RESTRICTIONS
|
||||
COPYRIGHT 1985,1986,1989 Massachusetts Institute of Technology
|
||||
@@ -1,257 +0,0 @@
|
||||
# Copyright 1987,1988 Massachusetts Institute of Technology
|
||||
# For copying and distribution information, see the file
|
||||
# "Copyright.MIT".
|
||||
#
|
||||
# from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $
|
||||
# $Id: krb_err.et,v 1.2 1994/07/19 19:25:44 g89r4222 Exp $
|
||||
#
|
||||
error_table krb
|
||||
|
||||
ec KRBET_KSUCCESS,
|
||||
"Kerberos successful"
|
||||
|
||||
ec KRBET_KDC_NAME_EXP,
|
||||
"Kerberos principal expired"
|
||||
|
||||
ec KRBET_KDC_SERVICE_EXP,
|
||||
"Kerberos service expired"
|
||||
|
||||
ec KRBET_KDC_AUTH_EXP,
|
||||
"Kerberos auth expired"
|
||||
|
||||
ec KRBET_KDC_PKT_VER,
|
||||
"Incorrect kerberos master key version"
|
||||
|
||||
ec KRBET_KDC_P_MKEY_VER,
|
||||
"Incorrect kerberos master key version"
|
||||
|
||||
ec KRBET_KDC_S_MKEY_VER,
|
||||
"Incorrect kerberos master key version"
|
||||
|
||||
ec KRBET_KDC_BYTE_ORDER,
|
||||
"Kerberos error: byte order unknown"
|
||||
|
||||
ec KRBET_KDC_PR_UNKNOWN,
|
||||
"Kerberos principal unknown"
|
||||
|
||||
ec KRBET_KDC_PR_N_UNIQUE,
|
||||
"Kerberos principal not unique"
|
||||
|
||||
ec KRBET_KDC_NULL_KEY,
|
||||
"Kerberos principal has null key"
|
||||
|
||||
ec KRBET_KRB_RES11,
|
||||
"Reserved 11"
|
||||
|
||||
ec KRBET_KRB_RES12,
|
||||
"Reserved 12"
|
||||
|
||||
ec KRBET_KRB_RES13,
|
||||
"Reserved 13"
|
||||
|
||||
ec KRBET_KRB_RES14,
|
||||
"Reserved 14"
|
||||
|
||||
ec KRBET_KRB_RES15,
|
||||
"Reserved 15"
|
||||
|
||||
ec KRBET_KRB_RES16,
|
||||
"Reserved 16"
|
||||
|
||||
ec KRBET_KRB_RES17,
|
||||
"Reserved 17"
|
||||
|
||||
ec KRBET_KRB_RES18,
|
||||
"Reserved 18"
|
||||
|
||||
ec KRBET_KRB_RES19,
|
||||
"Reserved 19"
|
||||
|
||||
ec KRBET_KDC_GEN_ERR,
|
||||
"Generic error from Kerberos KDC"
|
||||
|
||||
ec KRBET_GC_TKFIL,
|
||||
"Can't read Kerberos ticket file"
|
||||
|
||||
ec KRBET_GC_NOTKT,
|
||||
"Can't find Kerberos ticket or TGT"
|
||||
|
||||
ec KRBET_KRB_RES23,
|
||||
"Reserved 23"
|
||||
|
||||
ec KRBET_KRB_RES24,
|
||||
"Reserved 24"
|
||||
|
||||
ec KRBET_KRB_RES25,
|
||||
"Reserved 25"
|
||||
|
||||
ec KRBET_MK_AP_TGTEXP,
|
||||
"Kerberos TGT Expired"
|
||||
|
||||
ec KRBET_KRB_RES27,
|
||||
"Reserved 27"
|
||||
|
||||
ec KRBET_KRB_RES28,
|
||||
"Reserved 28"
|
||||
|
||||
ec KRBET_KRB_RES29,
|
||||
"Reserved 29"
|
||||
|
||||
ec KRBET_KRB_RES30,
|
||||
"Reserved 30"
|
||||
|
||||
ec KRBET_RD_AP_UNDEC,
|
||||
"Kerberos error: Can't decode authenticator"
|
||||
|
||||
ec KRBET_RD_AP_EXP,
|
||||
"Kerberos ticket expired"
|
||||
|
||||
ec KRBET_RD_AP_NYV,
|
||||
"Kerberos ticket not yet valid"
|
||||
|
||||
ec KRBET_RD_AP_REPEAT,
|
||||
"Kerberos error: Repeated request"
|
||||
|
||||
ec KRBET_RD_AP_NOT_US,
|
||||
"The kerberos ticket isn't for us"
|
||||
|
||||
ec KRBET_RD_AP_INCON,
|
||||
"Kerberos request inconsistent"
|
||||
|
||||
ec KRBET_RD_AP_TIME,
|
||||
"Kerberos error: delta_t too big"
|
||||
|
||||
ec KRBET_RD_AP_BADD,
|
||||
"Kerberos error: incorrect net address"
|
||||
|
||||
ec KRBET_RD_AP_VERSION,
|
||||
"Kerberos protocol version mismatch"
|
||||
|
||||
ec KRBET_RD_AP_MSG_TYPE,
|
||||
"Kerberos error: invalid msg type"
|
||||
|
||||
ec KRBET_RD_AP_MODIFIED,
|
||||
"Kerberos error: message stream modified"
|
||||
|
||||
ec KRBET_RD_AP_ORDER,
|
||||
"Kerberos error: message out of order"
|
||||
|
||||
ec KRBET_RD_AP_UNAUTHOR,
|
||||
"Kerberos error: unauthorized request"
|
||||
|
||||
ec KRBET_KRB_RES44,
|
||||
"Reserved 44"
|
||||
|
||||
ec KRBET_KRB_RES45,
|
||||
"Reserved 45"
|
||||
|
||||
ec KRBET_KRB_RES46,
|
||||
"Reserved 46"
|
||||
|
||||
ec KRBET_KRB_RES47,
|
||||
"Reserved 47"
|
||||
|
||||
ec KRBET_KRB_RES48,
|
||||
"Reserved 48"
|
||||
|
||||
ec KRBET_KRB_RES49,
|
||||
"Reserved 49"
|
||||
|
||||
ec KRBET_KRB_RES50,
|
||||
"Reserved 50"
|
||||
|
||||
ec KRBET_GT_PW_NULL,
|
||||
"Kerberos error: current PW is null"
|
||||
|
||||
ec KRBET_GT_PW_BADPW,
|
||||
"Kerberos error: Incorrect current password"
|
||||
|
||||
ec KRBET_GT_PW_PROT,
|
||||
"Kerberos protocol error"
|
||||
|
||||
ec KRBET_GT_PW_KDCERR,
|
||||
"Error returned by Kerberos KDC"
|
||||
|
||||
ec KRBET_GT_PW_NULLTKT,
|
||||
"Null Kerberos ticket returned by KDC"
|
||||
|
||||
ec KRBET_SKDC_RETRY,
|
||||
"Kerberos error: Retry count exceeded"
|
||||
|
||||
ec KRBET_SKDC_CANT,
|
||||
"Kerberos error: Can't send request"
|
||||
|
||||
ec KRBET_KRB_RES58,
|
||||
"Reserved 58"
|
||||
|
||||
ec KRBET_KRB_RES59,
|
||||
"Reserved 59"
|
||||
|
||||
ec KRBET_KRB_RES60,
|
||||
"Reserved 60"
|
||||
|
||||
ec KRBET_INTK_W_NOTALL,
|
||||
"Kerberos error: not all tickets returned"
|
||||
|
||||
ec KRBET_INTK_BADPW,
|
||||
"Kerberos error: incorrect password"
|
||||
|
||||
ec KRBET_INTK_PROT,
|
||||
"Kerberos error: Protocol Error"
|
||||
|
||||
ec KRBET_KRB_RES64,
|
||||
"Reserved 64"
|
||||
|
||||
ec KRBET_KRB_RES65,
|
||||
"Reserved 65"
|
||||
|
||||
ec KRBET_KRB_RES66,
|
||||
"Reserved 66"
|
||||
|
||||
ec KRBET_KRB_RES67,
|
||||
"Reserved 67"
|
||||
|
||||
ec KRBET_KRB_RES68,
|
||||
"Reserved 68"
|
||||
|
||||
ec KRBET_KRB_RES69,
|
||||
"Reserved 69"
|
||||
|
||||
ec KRBET_INTK_ERR,
|
||||
"Other error"
|
||||
|
||||
ec KRBET_AD_NOTGT,
|
||||
"Don't have Kerberos ticket-granting ticket"
|
||||
|
||||
ec KRBET_KRB_RES72,
|
||||
"Reserved 72"
|
||||
|
||||
ec KRBET_KRB_RES73,
|
||||
"Reserved 73"
|
||||
|
||||
ec KRBET_KRB_RES74,
|
||||
"Reserved 74"
|
||||
|
||||
ec KRBET_KRB_RES75,
|
||||
"Reserved 75"
|
||||
|
||||
ec KRBET_NO_TKT_FIL,
|
||||
"No ticket file found"
|
||||
|
||||
ec KRBET_TKT_FIL_ACC,
|
||||
"Couldn't access ticket file"
|
||||
|
||||
ec KRBET_TKT_FIL_LCK,
|
||||
"Couldn't lock ticket file"
|
||||
|
||||
ec KRBET_TKT_FIL_FMT,
|
||||
"Bad ticket file format"
|
||||
|
||||
ec KRBET_TKT_FIL_INI,
|
||||
"tf_init not called first"
|
||||
|
||||
ec KRBET_KNAME_FMT,
|
||||
"Bad Kerberos name format"
|
||||
|
||||
end
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $
|
||||
* $Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: krb_err_txt.c,v 1.2 1994/07/19 19:25:45 g89r4222 Exp $";
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
* This file contains an array of error text strings.
|
||||
* The associated error codes (which are defined in "krb.h")
|
||||
* follow the string in the comments at the end of each line.
|
||||
*/
|
||||
|
||||
char *krb_err_txt[256] = {
|
||||
"OK", /* 000 */
|
||||
"Principal expired (kerberos)", /* 001 */
|
||||
"Service expired (kerberos)", /* 002 */
|
||||
"Authentication expired (kerberos)", /* 003 */
|
||||
"Unknown protocol version number (kerberos)", /* 004 */
|
||||
"Principal: Incorrect master key version (kerberos)", /* 005 */
|
||||
"Service: Incorrect master key version (kerberos)", /* 006 */
|
||||
"Bad byte order (kerberos)", /* 007 */
|
||||
"Principal unknown (kerberos)", /* 008 */
|
||||
"Principal not unique (kerberos)", /* 009 */
|
||||
"Principal has null key (kerberos)", /* 010 */
|
||||
"Reserved error message 11 (kerberos)", /* 011 */
|
||||
"Reserved error message 12 (kerberos)", /* 012 */
|
||||
"Reserved error message 13 (kerberos)", /* 013 */
|
||||
"Reserved error message 14 (kerberos)", /* 014 */
|
||||
"Reserved error message 15 (kerberos)", /* 015 */
|
||||
"Reserved error message 16 (kerberos)", /* 016 */
|
||||
"Reserved error message 17 (kerberos)", /* 017 */
|
||||
"Reserved error message 18 (kerberos)", /* 018 */
|
||||
"Reserved error message 19 (kerberos)", /* 019 */
|
||||
"Permission Denied (kerberos)", /* 020 */
|
||||
"Can't read ticket file (krb_get_cred)", /* 021 */
|
||||
"Can't find ticket (krb_get_cred)", /* 022 */
|
||||
"Reserved error message 23 (krb_get_cred)", /* 023 */
|
||||
"Reserved error message 24 (krb_get_cred)", /* 024 */
|
||||
"Reserved error message 25 (krb_get_cred)", /* 025 */
|
||||
"Ticket granting ticket expired (krb_mk_req)", /* 026 */
|
||||
"Reserved error message 27 (krb_mk_req)", /* 027 */
|
||||
"Reserved error message 28 (krb_mk_req)", /* 028 */
|
||||
"Reserved error message 29 (krb_mk_req)", /* 029 */
|
||||
"Reserved error message 30 (krb_mk_req)", /* 030 */
|
||||
"Can't decode authenticator (krb_rd_req)", /* 031 */
|
||||
"Ticket expired (krb_rd_req)", /* 032 */
|
||||
"Ticket issue date too far in the future (krb_rd_req)",/* 033 */
|
||||
"Repeat request (krb_rd_req)", /* 034 */
|
||||
"Ticket for wrong server (krb_rd_req)", /* 035 */
|
||||
"Request inconsistent (krb_rd_req)", /* 036 */
|
||||
"Time is out of bounds (krb_rd_req)", /* 037 */
|
||||
"Incorrect network address (krb_rd_req)", /* 038 */
|
||||
"Protocol version mismatch (krb_rd_req)", /* 039 */
|
||||
"Illegal message type (krb_rd_req)", /* 040 */
|
||||
"Message integrity error (krb_rd_req)", /* 041 */
|
||||
"Message duplicate or out of order (krb_rd_req)", /* 042 */
|
||||
"Unauthorized request (krb_rd_req)", /* 043 */
|
||||
"Reserved error message 44 (krb_rd_req)", /* 044 */
|
||||
"Reserved error message 45 (krb_rd_req)", /* 045 */
|
||||
"Reserved error message 46 (krb_rd_req)", /* 046 */
|
||||
"Reserved error message 47 (krb_rd_req)", /* 047 */
|
||||
"Reserved error message 48 (krb_rd_req)", /* 048 */
|
||||
"Reserved error message 49 (krb_rd_req)", /* 049 */
|
||||
"Reserved error message 50 (krb_rd_req)", /* 050 */
|
||||
"Current password is NULL (get_pw_tkt)", /* 051 */
|
||||
"Current password incorrect (get_pw_tkt)", /* 052 */
|
||||
"Protocol error (gt_pw_tkt)", /* 053 */
|
||||
"Error returned by KDC (gt_pw_tkt)", /* 054 */
|
||||
"Null ticket returned by KDC (gt_pw_tkt)", /* 055 */
|
||||
"Retry count exceeded (send_to_kdc)", /* 056 */
|
||||
"Can't send request (send_to_kdc)", /* 057 */
|
||||
"Reserved error message 58 (send_to_kdc)", /* 058 */
|
||||
"Reserved error message 59 (send_to_kdc)", /* 059 */
|
||||
"Reserved error message 60 (send_to_kdc)", /* 060 */
|
||||
"Warning: Not ALL tickets returned", /* 061 */
|
||||
"Password incorrect", /* 062 */
|
||||
"Protocol error (get_intkt)", /* 063 */
|
||||
"Reserved error message 64 (get_in_tkt)", /* 064 */
|
||||
"Reserved error message 65 (get_in_tkt)", /* 065 */
|
||||
"Reserved error message 66 (get_in_tkt)", /* 066 */
|
||||
"Reserved error message 67 (get_in_tkt)", /* 067 */
|
||||
"Reserved error message 68 (get_in_tkt)", /* 068 */
|
||||
"Reserved error message 69 (get_in_tkt)", /* 069 */
|
||||
"Generic error (get_intkt)", /* 070 */
|
||||
"Don't have ticket granting ticket (get_ad_tkt)", /* 071 */
|
||||
"Reserved error message 72 (get_ad_tkt)", /* 072 */
|
||||
"Reserved error message 73 (get_ad_tkt)", /* 073 */
|
||||
"Reserved error message 74 (get_ad_tkt)", /* 074 */
|
||||
"Reserved error message 75 (get_ad_tkt)", /* 075 */
|
||||
"No ticket file (tf_util)", /* 076 */
|
||||
"Can't access ticket file (tf_util)", /* 077 */
|
||||
"Can't lock ticket file; try later (tf_util)", /* 078 */
|
||||
"Bad ticket file format (tf_util)", /* 079 */
|
||||
"Read ticket file before tf_init (tf_util)", /* 080 */
|
||||
"Bad Kerberos name format (kname_parse)", /* 081 */
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"(reserved)",
|
||||
"Generic kerberos error (kfailure)", /* 255 */
|
||||
};
|
||||
@@ -1,297 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: der: krb_get_in_tkt.c,v 4.19 89/07/18 16:31:31 jtkohl Exp $
|
||||
* $Id: krb_get_in_tkt.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: krb_get_in_tkt.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <des.h>
|
||||
#include <prot.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* use the bsd time.h struct defs for PC too! */
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
int swap_bytes;
|
||||
|
||||
/*
|
||||
* decrypt_tkt(): Given user, instance, realm, passwd, key_proc
|
||||
* and the cipher text sent from the KDC, decrypt the cipher text
|
||||
* using the key returned by key_proc.
|
||||
*/
|
||||
|
||||
static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
|
||||
char *user;
|
||||
char *instance;
|
||||
char *realm;
|
||||
char *arg;
|
||||
int (*key_proc)();
|
||||
KTEXT *cipp;
|
||||
{
|
||||
KTEXT cip = *cipp;
|
||||
C_Block key; /* Key for decrypting cipher */
|
||||
Key_schedule key_s;
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
/* Attempt to decrypt it */
|
||||
#endif
|
||||
|
||||
/* generate a key */
|
||||
|
||||
{
|
||||
register int rc;
|
||||
rc = (*key_proc)(user,instance,realm,arg,key);
|
||||
if (rc)
|
||||
return(rc);
|
||||
}
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(key,key_s);
|
||||
pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
|
||||
(long) cip->length,key_s,key,DES_DECRYPT);
|
||||
#endif /* !NOENCRYPTION */
|
||||
/* Get rid of all traces of key */
|
||||
bzero((char *)key,sizeof(key));
|
||||
bzero((char *)key_s,sizeof(key_s));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* krb_get_in_tkt() gets a ticket for a given principal to use a given
|
||||
* service and stores the returned ticket and session key for future
|
||||
* use.
|
||||
*
|
||||
* The "user", "instance", and "realm" arguments give the identity of
|
||||
* the client who will use the ticket. The "service" and "sinstance"
|
||||
* arguments give the identity of the server that the client wishes
|
||||
* to use. (The realm of the server is the same as the Kerberos server
|
||||
* to whom the request is sent.) The "life" argument indicates the
|
||||
* desired lifetime of the ticket; the "key_proc" argument is a pointer
|
||||
* to the routine used for getting the client's private key to decrypt
|
||||
* the reply from Kerberos. The "decrypt_proc" argument is a pointer
|
||||
* to the routine used to decrypt the reply from Kerberos; and "arg"
|
||||
* is an argument to be passed on to the "key_proc" routine.
|
||||
*
|
||||
* If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
|
||||
* returns an error code: If an AUTH_MSG_ERR_REPLY packet is returned
|
||||
* by Kerberos, then the error code it contains is returned. Other
|
||||
* error codes returned by this routine include INTK_PROT to indicate
|
||||
* wrong protocol version, INTK_BADPW to indicate bad password (if
|
||||
* decrypted ticket didn't make sense), INTK_ERR if the ticket was for
|
||||
* the wrong server or the ticket store couldn't be initialized.
|
||||
*
|
||||
* The format of the message sent to Kerberos is as follows:
|
||||
*
|
||||
* Size Variable Field
|
||||
* ---- -------- -----
|
||||
*
|
||||
* 1 byte KRB_PROT_VERSION protocol version number
|
||||
* 1 byte AUTH_MSG_KDC_REQUEST | message type
|
||||
* HOST_BYTE_ORDER local byte order in lsb
|
||||
* string user client's name
|
||||
* string instance client's instance
|
||||
* string realm client's realm
|
||||
* 4 bytes tlocal.tv_sec timestamp in seconds
|
||||
* 1 byte life desired lifetime
|
||||
* string service service's name
|
||||
* string sinstance service's instance
|
||||
*/
|
||||
|
||||
krb_get_in_tkt(user, instance, realm, service, sinstance, life,
|
||||
key_proc, decrypt_proc, arg)
|
||||
char *user;
|
||||
char *instance;
|
||||
char *realm;
|
||||
char *service;
|
||||
char *sinstance;
|
||||
int life;
|
||||
int (*key_proc)();
|
||||
int (*decrypt_proc)();
|
||||
char *arg;
|
||||
{
|
||||
KTEXT_ST pkt_st;
|
||||
KTEXT pkt = &pkt_st; /* Packet to KDC */
|
||||
KTEXT_ST rpkt_st;
|
||||
KTEXT rpkt = &rpkt_st; /* Returned packet */
|
||||
KTEXT_ST cip_st;
|
||||
KTEXT cip = &cip_st; /* Returned Ciphertext */
|
||||
KTEXT_ST tkt_st;
|
||||
KTEXT tkt = &tkt_st; /* Current ticket */
|
||||
C_Block ses; /* Session key for tkt */
|
||||
int kvno; /* Kvno for session key */
|
||||
unsigned char *v = pkt->dat; /* Prot vers no */
|
||||
unsigned char *t = (pkt->dat+1); /* Prot msg type */
|
||||
|
||||
char s_name[SNAME_SZ];
|
||||
char s_instance[INST_SZ];
|
||||
char rlm[REALM_SZ];
|
||||
int lifetime;
|
||||
int msg_byte_order;
|
||||
int kerror;
|
||||
unsigned long exp_date;
|
||||
char *ptr;
|
||||
|
||||
struct timeval t_local;
|
||||
|
||||
unsigned long rep_err_code;
|
||||
|
||||
unsigned long kdc_time; /* KDC time */
|
||||
|
||||
/* BUILD REQUEST PACKET */
|
||||
|
||||
/* Set up the fixed part of the packet */
|
||||
*v = (unsigned char) KRB_PROT_VERSION;
|
||||
*t = (unsigned char) AUTH_MSG_KDC_REQUEST;
|
||||
*t |= HOST_BYTE_ORDER;
|
||||
|
||||
/* Now for the variable info */
|
||||
(void) strcpy((char *)(pkt->dat+2),user); /* aname */
|
||||
pkt->length = 3 + strlen(user);
|
||||
(void) strcpy((char *)(pkt->dat+pkt->length),
|
||||
instance); /* instance */
|
||||
pkt->length += 1 + strlen(instance);
|
||||
(void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
|
||||
pkt->length += 1 + strlen(realm);
|
||||
|
||||
(void) gettimeofday(&t_local,(struct timezone *) 0);
|
||||
/* timestamp */
|
||||
bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4);
|
||||
pkt->length += 4;
|
||||
|
||||
*(pkt->dat+(pkt->length)++) = (char) life;
|
||||
(void) strcpy((char *)(pkt->dat+pkt->length),service);
|
||||
pkt->length += 1 + strlen(service);
|
||||
(void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
|
||||
pkt->length += 1 + strlen(sinstance);
|
||||
|
||||
rpkt->length = 0;
|
||||
|
||||
/* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
|
||||
|
||||
if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
|
||||
|
||||
/* check packet version of the returned packet */
|
||||
if (pkt_version(rpkt) != KRB_PROT_VERSION)
|
||||
return(INTK_PROT);
|
||||
|
||||
/* Check byte order */
|
||||
msg_byte_order = pkt_msg_type(rpkt) & 1;
|
||||
swap_bytes = 0;
|
||||
if (msg_byte_order != HOST_BYTE_ORDER) {
|
||||
swap_bytes++;
|
||||
}
|
||||
|
||||
switch (pkt_msg_type(rpkt) & ~1) {
|
||||
case AUTH_MSG_KDC_REPLY:
|
||||
break;
|
||||
case AUTH_MSG_ERR_REPLY:
|
||||
bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4);
|
||||
if (swap_bytes) swap_u_long(rep_err_code);
|
||||
return((int)rep_err_code);
|
||||
default:
|
||||
return(INTK_PROT);
|
||||
}
|
||||
|
||||
/* EXTRACT INFORMATION FROM RETURN PACKET */
|
||||
|
||||
/* get the principal's expiration date */
|
||||
bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date));
|
||||
if (swap_bytes) swap_u_long(exp_date);
|
||||
|
||||
/* Extract the ciphertext */
|
||||
cip->length = pkt_clen(rpkt); /* let clen do the swap */
|
||||
|
||||
if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
|
||||
return(INTK_ERR); /* no appropriate error code
|
||||
currently defined for INTK_ */
|
||||
/* copy information from return packet into "cip" */
|
||||
bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length);
|
||||
|
||||
/* Attempt to decrypt the reply. */
|
||||
if (decrypt_proc == NULL)
|
||||
decrypt_proc = decrypt_tkt;
|
||||
(*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
|
||||
|
||||
ptr = (char *) cip->dat;
|
||||
|
||||
/* extract session key */
|
||||
bcopy(ptr,(char *)ses,8);
|
||||
ptr += 8;
|
||||
|
||||
if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
|
||||
return(INTK_BADPW);
|
||||
|
||||
/* extract server's name */
|
||||
(void) strcpy(s_name,ptr);
|
||||
ptr += strlen(s_name) + 1;
|
||||
|
||||
if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
|
||||
return(INTK_BADPW);
|
||||
|
||||
/* extract server's instance */
|
||||
(void) strcpy(s_instance,ptr);
|
||||
ptr += strlen(s_instance) + 1;
|
||||
|
||||
if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
|
||||
return(INTK_BADPW);
|
||||
|
||||
/* extract server's realm */
|
||||
(void) strcpy(rlm,ptr);
|
||||
ptr += strlen(rlm) + 1;
|
||||
|
||||
/* extract ticket lifetime, server key version, ticket length */
|
||||
/* be sure to avoid sign extension on lifetime! */
|
||||
lifetime = (unsigned char) ptr[0];
|
||||
kvno = (unsigned char) ptr[1];
|
||||
tkt->length = (unsigned char) ptr[2];
|
||||
ptr += 3;
|
||||
|
||||
if ((tkt->length < 0) ||
|
||||
((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
|
||||
return(INTK_BADPW);
|
||||
|
||||
/* extract ticket itself */
|
||||
bcopy(ptr,(char *)(tkt->dat),tkt->length);
|
||||
ptr += tkt->length;
|
||||
|
||||
if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
|
||||
strcmp(rlm, realm)) /* not what we asked for */
|
||||
return(INTK_ERR); /* we need a better code here XXX */
|
||||
|
||||
/* check KDC time stamp */
|
||||
bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
|
||||
if (swap_bytes) swap_u_long(kdc_time);
|
||||
|
||||
ptr += 4;
|
||||
|
||||
(void) gettimeofday(&t_local,(struct timezone *) 0);
|
||||
if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
|
||||
return(RD_AP_TIME); /* XXX should probably be better
|
||||
code */
|
||||
}
|
||||
|
||||
/* initialize ticket cache */
|
||||
if (in_tkt(user,instance) != KSUCCESS)
|
||||
return(INTK_ERR);
|
||||
|
||||
/* stash ticket, session key, etc. for future use */
|
||||
if (kerror = save_credentials(s_name, s_instance, rlm, ses,
|
||||
lifetime, kvno, tkt, t_local.tv_sec))
|
||||
return(kerror);
|
||||
|
||||
return(INTK_OK);
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
.\" from: krb_realmofhost.3,v 4.1 89/01/23 11:10:47 jtkohl Exp $
|
||||
.\" $Id: krb_realmofhost.3,v 1.1.1.1 1994/09/30 14:50:07 csgr Exp $
|
||||
.\" Copyright 1989 by the Massachusetts Institute of Technology.
|
||||
.\"
|
||||
.\" For copying and distribution information,
|
||||
.\" please see the file <Copyright.MIT>.
|
||||
.\"
|
||||
.TH KRB_REALMOFHOST 3 "Kerberos Version 4.0" "MIT Project Athena"
|
||||
.SH NAME
|
||||
krb_realmofhost, krb_get_phost, krb_get_krbhst, krb_get_admhst,
|
||||
krb_get_lrealm \- additional Kerberos utility routines
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.nj
|
||||
.ft B
|
||||
#include <kerberosIV/krb.h>
|
||||
#include <kerberosIV/des.h>
|
||||
#include <netinet/in.h>
|
||||
.PP
|
||||
.ft B
|
||||
char *krb_realmofhost(host)
|
||||
char *host;
|
||||
.PP
|
||||
.ft B
|
||||
char *krb_get_phost(alias)
|
||||
char *alias;
|
||||
.PP
|
||||
.ft B
|
||||
krb_get_krbhst(host,realm,n)
|
||||
char *host;
|
||||
char *realm;
|
||||
int n;
|
||||
.PP
|
||||
.ft B
|
||||
krb_get_admhst(host,realm,n)
|
||||
char *host;
|
||||
char *realm;
|
||||
int n;
|
||||
.PP
|
||||
.ft B
|
||||
krb_get_lrealm(realm,n)
|
||||
char *realm;
|
||||
int n;
|
||||
.fi
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
.I krb_realmofhost
|
||||
returns the Kerberos realm of the host
|
||||
.IR host ,
|
||||
as determined by the translation table
|
||||
.IR /etc/kerberosIV/krb.realms .
|
||||
.I host
|
||||
should be the fully-qualified domain-style primary host name of the host
|
||||
in question. In order to prevent certain security attacks, this routine
|
||||
must either have
|
||||
.I a priori
|
||||
knowledge of a host's realm, or obtain such information securely.
|
||||
.PP
|
||||
The format of the translation file is described by
|
||||
.IR krb.realms (5).
|
||||
If
|
||||
.I host
|
||||
exactly matches a host_name line, the corresponding realm
|
||||
is returned.
|
||||
Otherwise, if the domain portion of
|
||||
.I host
|
||||
matches a domain_name line, the corresponding realm
|
||||
is returned.
|
||||
If
|
||||
.I host
|
||||
contains a domain, but no translation is found,
|
||||
.IR host 's
|
||||
domain is converted to upper-case and returned.
|
||||
If
|
||||
.I host
|
||||
contains no discernable domain, or an error occurs,
|
||||
the local realm name, as supplied by
|
||||
.IR krb_get_lrealm (3),
|
||||
is returned.
|
||||
.PP
|
||||
.I krb_get_phost
|
||||
converts the hostname
|
||||
.I alias
|
||||
(which can be either an official name or an alias) into the instance
|
||||
name to be used in obtaining Kerberos tickets for most services,
|
||||
including the Berkeley rcmd suite (rlogin, rcp, rsh).
|
||||
.br
|
||||
The current convention is to return the first segment of the official
|
||||
domain-style name after conversion to lower case.
|
||||
.PP
|
||||
.I krb_get_krbhst
|
||||
fills in
|
||||
.I host
|
||||
with the hostname of the
|
||||
.IR n th
|
||||
host running a Kerberos key distribution center (KDC)
|
||||
for realm
|
||||
.IR realm ,
|
||||
as specified in the configuration file (\fI/etc/kerberosIV/krb.conf\fR).
|
||||
The configuration file is described by
|
||||
.IR krb.conf (5).
|
||||
If the host is successfully filled in, the routine
|
||||
returns KSUCCESS.
|
||||
If the file cannot be opened, and
|
||||
.I n
|
||||
equals 1, then the value of KRB_HOST as defined in
|
||||
.I <krb.h>
|
||||
is filled in, and KSUCCESS is returned. If there are fewer than
|
||||
.I n
|
||||
hosts running a Kerberos KDC for the requested realm, or the
|
||||
configuration file is malformed, the routine
|
||||
returns KFAILURE.
|
||||
.PP
|
||||
.I krb_get_admhst
|
||||
fills in
|
||||
.I host
|
||||
with the hostname of the
|
||||
.IR n th
|
||||
host running a Kerberos KDC database administration server
|
||||
for realm
|
||||
.IR realm ,
|
||||
as specified in the configuration file (\fI/etc/kerberosIV/krb.conf\fR).
|
||||
If the file cannot be opened or is malformed, or there are fewer than
|
||||
.I n
|
||||
hosts running a Kerberos KDC database administration server,
|
||||
the routine returns KFAILURE.
|
||||
.PP
|
||||
The character arrays used as return values for
|
||||
.IR krb_get_krbhst ,
|
||||
.IR krb_get_admhst ,
|
||||
should be large enough to
|
||||
hold any hostname (MAXHOSTNAMELEN from <sys/param.h>).
|
||||
.PP
|
||||
.I krb_get_lrealm
|
||||
fills in
|
||||
.I realm
|
||||
with the
|
||||
.IR n th
|
||||
realm of the local host, as specified in the configuration file.
|
||||
.I realm
|
||||
should be at least REALM_SZ (from
|
||||
.IR <krb.h>) characters long.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
kerberos(3), krb.conf(5), krb.realms(5)
|
||||
.SH FILES
|
||||
.TP 20n
|
||||
/etc/kerberosIV/krb.realms
|
||||
translation file for host-to-realm mapping.
|
||||
.TP
|
||||
/etc/kerberosIV/krb.conf
|
||||
local realm-name and realm/server configuration file.
|
||||
.SH BUGS
|
||||
The current convention for instance names is too limited; the full
|
||||
domain name should be used.
|
||||
.PP
|
||||
.I krb_get_lrealm
|
||||
currently only supports
|
||||
.I n
|
||||
= 1. It should really consult the user's ticket cache to determine the
|
||||
user's current realm, rather than consulting a file on the host.
|
||||
@@ -1,348 +0,0 @@
|
||||
.\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $
|
||||
.\" $Id: krb_sendauth.3,v 1.1.1.1 1994/09/30 14:50:07 csgr Exp $
|
||||
.\" Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
.\"
|
||||
.\" For copying and distribution information,
|
||||
.\" please see the file <Copyright.MIT>.
|
||||
.\"
|
||||
.TH KRB_SENDAUTH 3 "Kerberos Version 4.0" "MIT Project Athena"
|
||||
.SH NAME
|
||||
krb_sendauth, krb_recvauth, krb_net_write, krb_net_read \-
|
||||
Kerberos routines for sending authentication via network stream sockets
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.nj
|
||||
.ft B
|
||||
#include <kerberosIV/krb.h>
|
||||
#include <kerberosIV/des.h>
|
||||
#include <netinet/in.h>
|
||||
.PP
|
||||
.fi
|
||||
.HP 1i
|
||||
.ft B
|
||||
int krb_sendauth(options, fd, ktext, service, inst, realm, checksum,
|
||||
msg_data, cred, schedule, laddr, faddr, version)
|
||||
.nf
|
||||
.RS 0
|
||||
.ft B
|
||||
long options;
|
||||
int fd;
|
||||
KTEXT ktext;
|
||||
char *service, *inst, *realm;
|
||||
u_long checksum;
|
||||
MSG_DAT *msg_data;
|
||||
CREDENTIALS *cred;
|
||||
Key_schedule schedule;
|
||||
struct sockaddr_in *laddr, *faddr;
|
||||
char *version;
|
||||
.PP
|
||||
.fi
|
||||
.HP 1i
|
||||
.ft B
|
||||
int krb_recvauth(options, fd, ktext, service, inst, faddr, laddr,
|
||||
auth_data, filename, schedule, version)
|
||||
.nf
|
||||
.RS 0
|
||||
.ft B
|
||||
long options;
|
||||
int fd;
|
||||
KTEXT ktext;
|
||||
char *service, *inst;
|
||||
struct sockaddr_in *faddr, *laddr;
|
||||
AUTH_DAT *auth_data;
|
||||
char *filename;
|
||||
Key_schedule schedule;
|
||||
char *version;
|
||||
.PP
|
||||
.ft B
|
||||
int krb_net_write(fd, buf, len)
|
||||
int fd;
|
||||
char *buf;
|
||||
int len;
|
||||
.PP
|
||||
.ft B
|
||||
int krb_net_read(fd, buf, len)
|
||||
int fd;
|
||||
char *buf;
|
||||
int len;
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
These functions,
|
||||
which are built on top of the core Kerberos library,
|
||||
provide a convenient means for client and server
|
||||
programs to send authentication messages
|
||||
to one another through network connections.
|
||||
The
|
||||
.I krb_sendauth
|
||||
function sends an authenticated ticket from the client program to
|
||||
the server program by writing the ticket to a network socket.
|
||||
The
|
||||
.I krb_recvauth
|
||||
function receives the ticket from the client by
|
||||
reading from a network socket.
|
||||
|
||||
.SH KRB_SENDAUTH
|
||||
.PP
|
||||
This function writes the ticket to
|
||||
the network socket specified by the
|
||||
file descriptor
|
||||
.IR fd,
|
||||
returning KSUCCESS if the write proceeds successfully,
|
||||
and an error code if it does not.
|
||||
|
||||
The
|
||||
.I ktext
|
||||
argument should point to an allocated KTEXT_ST structure.
|
||||
The
|
||||
.IR service,
|
||||
.IR inst,
|
||||
and
|
||||
.IR realm
|
||||
arguments specify the server program's Kerberos principal name,
|
||||
instance, and realm.
|
||||
If you are writing a client that uses the local realm exclusively,
|
||||
you can set the
|
||||
.I realm
|
||||
argument to NULL.
|
||||
|
||||
The
|
||||
.I version
|
||||
argument allows the client program to pass an application-specific
|
||||
version string that the server program can then match against
|
||||
its own version string.
|
||||
The
|
||||
.I version
|
||||
string can be up to KSEND_VNO_LEN (see
|
||||
.IR <krb.h> )
|
||||
characters in length.
|
||||
|
||||
The
|
||||
.I checksum
|
||||
argument can be used to pass checksum information to the
|
||||
server program.
|
||||
The client program is responsible for specifying this information.
|
||||
This checksum information is difficult to corrupt because
|
||||
.I krb_sendauth
|
||||
passes it over the network in encrypted form.
|
||||
The
|
||||
.I checksum
|
||||
argument is passed as the checksum argument to
|
||||
.IR krb_mk_req .
|
||||
|
||||
You can set
|
||||
.IR krb_sendauth's
|
||||
other arguments to NULL unless you want the
|
||||
client and server programs to mutually authenticate
|
||||
themselves.
|
||||
In the case of mutual authentication,
|
||||
the client authenticates itself to the server program,
|
||||
and demands that the server in turn authenticate itself to
|
||||
the client.
|
||||
|
||||
.SH KRB_SENDAUTH AND MUTUAL AUTHENTICATION
|
||||
.PP
|
||||
If you want mutual authentication,
|
||||
make sure that you read all pending data from the local socket
|
||||
before calling
|
||||
.IR krb_sendauth.
|
||||
Set
|
||||
.IR krb_sendauth's
|
||||
.I options
|
||||
argument to
|
||||
.BR KOPT_DO_MUTUAL
|
||||
(this macro is defined in the
|
||||
.IR krb.h
|
||||
file);
|
||||
make sure that the
|
||||
.I laddr
|
||||
argument points to
|
||||
the address of the local socket,
|
||||
and that
|
||||
.I faddr
|
||||
points to the foreign socket's network address.
|
||||
|
||||
.I Krb_sendauth
|
||||
fills in the other arguments--
|
||||
.IR msg_data ,
|
||||
.IR cred ,
|
||||
and
|
||||
.IR schedule --before
|
||||
sending the ticket to the server program.
|
||||
You must, however, allocate space for these arguments
|
||||
before calling the function.
|
||||
|
||||
.I Krb_sendauth
|
||||
supports two other options:
|
||||
.BR KOPT_DONT_MK_REQ,
|
||||
and
|
||||
.BR KOPT_DONT_CANON.
|
||||
If called with
|
||||
.I options
|
||||
set as KOPT_DONT_MK_REQ,
|
||||
.I krb_sendauth
|
||||
will not use the
|
||||
.I krb_mk_req
|
||||
function to retrieve the ticket from the Kerberos server.
|
||||
The
|
||||
.I ktext
|
||||
argument must point to an existing ticket and authenticator (such as
|
||||
would be created by
|
||||
.IR krb_mk_req ),
|
||||
and the
|
||||
.IR service,
|
||||
.IR inst,
|
||||
and
|
||||
.IR realm
|
||||
arguments can be set to NULL.
|
||||
|
||||
If called with
|
||||
.I options
|
||||
set as KOPT_DONT_CANON,
|
||||
.I krb_sendauth
|
||||
will not convert the service's instance to canonical form using
|
||||
.IR krb_get_phost (3).
|
||||
|
||||
If you want to call
|
||||
.I krb_sendauth
|
||||
with a multiple
|
||||
.I options
|
||||
specification,
|
||||
construct
|
||||
.I options
|
||||
as a bitwise-OR of the options you want to specify.
|
||||
|
||||
.SH KRB_RECVAUTH
|
||||
.PP
|
||||
The
|
||||
.I krb_recvauth
|
||||
function
|
||||
reads a ticket/authenticator pair from the socket pointed to by the
|
||||
.I fd
|
||||
argument.
|
||||
Set the
|
||||
.I options
|
||||
argument
|
||||
as a bitwise-OR of the options desired.
|
||||
Currently only KOPT_DO_MUTUAL is useful to the receiver.
|
||||
|
||||
The
|
||||
.I ktext
|
||||
argument
|
||||
should point to an allocated KTEXT_ST structure.
|
||||
.I Krb_recvauth
|
||||
fills
|
||||
.I ktext
|
||||
with the
|
||||
ticket/authenticator pair read from
|
||||
.IR fd ,
|
||||
then passes it to
|
||||
.IR krb_rd_req .
|
||||
|
||||
The
|
||||
.I service
|
||||
and
|
||||
.I inst
|
||||
arguments
|
||||
specify the expected service and instance for which the ticket was
|
||||
generated. They are also passed to
|
||||
.IR krb_rd_req.
|
||||
The
|
||||
.I inst
|
||||
argument may be set to "*" if the caller wishes
|
||||
.I krb_mk_req
|
||||
to fill in the instance used (note that there must be space in the
|
||||
.I inst
|
||||
argument to hold a full instance name, see
|
||||
.IR krb_mk_req (3)).
|
||||
|
||||
The
|
||||
.I faddr
|
||||
argument
|
||||
should point to the address of the peer which is presenting the ticket.
|
||||
It is also passed to
|
||||
.IR krb_rd_req .
|
||||
|
||||
If the client and server plan to mutually authenticate
|
||||
one another,
|
||||
the
|
||||
.I laddr
|
||||
argument
|
||||
should point to the local address of the file descriptor.
|
||||
Otherwise you can set this argument to NULL.
|
||||
|
||||
The
|
||||
.I auth_data
|
||||
argument
|
||||
should point to an allocated AUTH_DAT area.
|
||||
It is passed to and filled in by
|
||||
.IR krb_rd_req .
|
||||
The checksum passed to the corresponding
|
||||
.I krb_sendauth
|
||||
is available as part of the filled-in AUTH_DAT area.
|
||||
|
||||
The
|
||||
.I filename
|
||||
argument
|
||||
specifies the filename
|
||||
which the service program should use to obtain its service key.
|
||||
.I Krb_recvauth
|
||||
passes
|
||||
.I filename
|
||||
to the
|
||||
.I krb_rd_req
|
||||
function.
|
||||
If you set this argument to "",
|
||||
.I krb_rd_req
|
||||
looks for the service key in the file
|
||||
.IR /etc/kerberosIV/srvtab.
|
||||
|
||||
If the client and server are performing mutual authenication,
|
||||
the
|
||||
.I schedule
|
||||
argument
|
||||
should point to an allocated Key_schedule.
|
||||
Otherwise it is ignored and may be NULL.
|
||||
|
||||
The
|
||||
.I version
|
||||
argument should point to a character array of at least KSEND_VNO_LEN
|
||||
characters. It is filled in with the version string passed by the client to
|
||||
.IR krb_sendauth.
|
||||
.PP
|
||||
.SH KRB_NET_WRITE AND KRB_NET_READ
|
||||
.PP
|
||||
The
|
||||
.I krb_net_write
|
||||
function
|
||||
emulates the write(2) system call, but guarantees that all data
|
||||
specified is written to
|
||||
.I fd
|
||||
before returning, unless an error condition occurs.
|
||||
.PP
|
||||
The
|
||||
.I krb_net_read
|
||||
function
|
||||
emulates the read(2) system call, but guarantees that the requested
|
||||
amount of data is read from
|
||||
.I fd
|
||||
before returning, unless an error condition occurs.
|
||||
.PP
|
||||
.SH BUGS
|
||||
.IR krb_sendauth,
|
||||
.IR krb_recvauth,
|
||||
.IR krb_net_write,
|
||||
and
|
||||
.IR krb_net_read
|
||||
will not work properly on sockets set to non-blocking I/O mode.
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
krb_mk_req(3), krb_rd_req(3), krb_get_phost(3)
|
||||
|
||||
.SH AUTHOR
|
||||
John T. Kohl, MIT Project Athena
|
||||
.SH RESTRICTIONS
|
||||
Copyright 1988, Massachusetts Instititute of Technology.
|
||||
For copying and distribution information,
|
||||
please see the file <Copyright.h>.
|
||||
@@ -1,43 +0,0 @@
|
||||
.\" from: krb_set_tkt_string.3,v 4.1 89/01/23 11:11:09 jtkohl Exp $
|
||||
.\" $Id: krb_set_tkt_string.3,v 1.1.1.1 1994/09/30 14:50:07 csgr Exp $
|
||||
.\" Copyright 1989 by the Massachusetts Institute of Technology.
|
||||
.\"
|
||||
.\" For copying and distribution information,
|
||||
.\" please see the file <Copyright.MIT>.
|
||||
.\"
|
||||
.TH KRB_SET_TKT_STRING 3 "Kerberos Version 4.0" "MIT Project Athena"
|
||||
.SH NAME
|
||||
krb_set_tkt_string \- set Kerberos ticket cache file name
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.nj
|
||||
.ft B
|
||||
#include <kerberosIV/krb.h>
|
||||
.PP
|
||||
.ft B
|
||||
void krb_set_tkt_string(filename)
|
||||
char *filename;
|
||||
.fi
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
.I krb_set_tkt_string
|
||||
sets the name of the file that holds the user's
|
||||
cache of Kerberos server tickets and associated session keys.
|
||||
.PP
|
||||
The string
|
||||
.I filename
|
||||
passed in is copied into local storage.
|
||||
Only MAXPATHLEN-1 (see <sys/param.h>) characters of the filename are
|
||||
copied in for use as the cache file name.
|
||||
.PP
|
||||
This routine should be called during initialization, before other
|
||||
Kerberos routines are called; otherwise the routines which fetch the
|
||||
ticket cache file name may be called and return an undesired ticket file
|
||||
name until this routine is called.
|
||||
.SH FILES
|
||||
.TP 20n
|
||||
/tmp/tkt[uid]
|
||||
default ticket file name, unless the environment variable KRBTKFILE is set.
|
||||
[uid] denotes the user's uid, in decimal.
|
||||
.SH SEE ALSO
|
||||
kerberos(3), setenv(3)
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: krbglue.c,v 4.1 89/01/23 15:51:50 wesommer Exp $
|
||||
* $Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
$Id: krbglue.c,v 1.2 1994/07/19 19:25:49 g89r4222 Exp $";
|
||||
#endif lint
|
||||
|
||||
#ifndef NCOMPAT
|
||||
/*
|
||||
* glue together new libraries and old clients
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include "des.h"
|
||||
#include "krb.h"
|
||||
|
||||
/* These definitions should be in krb.h, no? */
|
||||
#if defined(__HIGHC__)
|
||||
#undef __STDC__
|
||||
#endif
|
||||
#ifdef __STDC__
|
||||
extern int krb_mk_req (KTEXT, char *, char *, char *, long);
|
||||
extern int krb_rd_req (KTEXT, char *, char *, long, AUTH_DAT *, char *);
|
||||
extern int krb_kntoln (AUTH_DAT *, char *);
|
||||
extern int krb_set_key (char *, int);
|
||||
extern int krb_get_cred (char *, char *, char *, CREDENTIALS *);
|
||||
extern long krb_mk_priv (u_char *, u_char *, u_long, Key_schedule,
|
||||
C_Block, struct sockaddr_in *,
|
||||
struct sockaddr_in *);
|
||||
extern long krb_rd_priv (u_char *, u_long, Key_schedule,
|
||||
C_Block, struct sockaddr_in *,
|
||||
struct sockaddr_in *, MSG_DAT *);
|
||||
extern long krb_mk_safe (u_char *, u_char *, u_long, C_Block *,
|
||||
struct sockaddr_in *, struct sockaddr_in *);
|
||||
extern long krb_rd_safe (u_char *, u_long, C_Block *,
|
||||
struct sockaddr_in *, struct sockaddr_in *,
|
||||
MSG_DAT *);
|
||||
extern long krb_mk_err (u_char *, long, char *);
|
||||
extern int krb_rd_err (u_char *, u_long, long *, MSG_DAT *);
|
||||
extern int krb_get_pw_in_tkt (char *, char *, char *, char *, char *, int,
|
||||
char *);
|
||||
extern int krb_get_svc_in_tkt (char *, char *, char *, char *, char *, int,
|
||||
char *);
|
||||
extern int krb_get_pw_tkt (char *, char *, char *, char *);
|
||||
extern int krb_get_lrealm (char *, char *);
|
||||
extern int krb_realmofhost (char *);
|
||||
extern char *krb_get_phost (char *);
|
||||
extern int krb_get_krbhst (char *, char *, int);
|
||||
#ifdef DEBUG
|
||||
extern KTEXT krb_create_death_packet (char *);
|
||||
#endif /* DEBUG */
|
||||
#else
|
||||
extern int krb_mk_req ();
|
||||
extern int krb_rd_req ();
|
||||
extern int krb_kntoln ();
|
||||
extern int krb_set_key ();
|
||||
extern int krb_get_cred ();
|
||||
extern long krb_mk_priv ();
|
||||
extern long krb_rd_priv ();
|
||||
extern long krb_mk_safe ();
|
||||
extern long krb_rd_safe ();
|
||||
extern long krb_mk_err ();
|
||||
extern int krb_rd_err ();
|
||||
extern int krb_get_pw_in_tkt ();
|
||||
extern int krb_get_svc_in_tkt ();
|
||||
extern int krb_get_pw_tkt ();
|
||||
extern int krb_get_lrealm ();
|
||||
extern int krb_realmofhost ();
|
||||
extern char *krb_get_phost ();
|
||||
extern int krb_get_krbhst ();
|
||||
#ifdef DEBUG
|
||||
extern KTEXT krb_create_death_packet ();
|
||||
#endif /* DEBUG */
|
||||
#endif /* STDC */
|
||||
int mk_ap_req(authent, service, instance, realm, checksum)
|
||||
KTEXT authent;
|
||||
char *service, *instance, *realm;
|
||||
u_long checksum;
|
||||
{
|
||||
return krb_mk_req(authent,service,instance,realm,checksum);
|
||||
}
|
||||
|
||||
int rd_ap_req(authent, service, instance, from_addr, ad, fn)
|
||||
KTEXT authent;
|
||||
char *service, *instance;
|
||||
u_long from_addr;
|
||||
AUTH_DAT *ad;
|
||||
char *fn;
|
||||
{
|
||||
return krb_rd_req(authent,service,instance,from_addr,ad,fn);
|
||||
}
|
||||
|
||||
int an_to_ln(ad, lname)
|
||||
AUTH_DAT *ad;
|
||||
char *lname;
|
||||
{
|
||||
return krb_kntoln (ad,lname);
|
||||
}
|
||||
|
||||
int set_serv_key (key, cvt)
|
||||
char *key;
|
||||
int cvt;
|
||||
{
|
||||
return krb_set_key(key,cvt);
|
||||
}
|
||||
|
||||
int get_credentials (svc,inst,rlm,cred)
|
||||
char *svc, *inst, *rlm;
|
||||
CREDENTIALS *cred;
|
||||
{
|
||||
return krb_get_cred (svc, inst, rlm, cred);
|
||||
}
|
||||
|
||||
long mk_private_msg (in,out,in_length,schedule,key,sender,receiver)
|
||||
u_char *in, *out;
|
||||
u_long in_length;
|
||||
Key_schedule schedule;
|
||||
C_Block key;
|
||||
struct sockaddr_in *sender, *receiver;
|
||||
{
|
||||
return krb_mk_priv (in,out,in_length,schedule,key,sender,receiver);
|
||||
}
|
||||
|
||||
long rd_private_msg (in,in_length,schedule,key,sender,receiver,msg_data)
|
||||
u_char *in;
|
||||
u_long in_length;
|
||||
Key_schedule schedule;
|
||||
C_Block key;
|
||||
struct sockaddr_in *sender, *receiver;
|
||||
MSG_DAT *msg_data;
|
||||
{
|
||||
return krb_rd_priv (in,in_length,schedule,key,sender,receiver,msg_data);
|
||||
}
|
||||
|
||||
long mk_safe_msg (in,out,in_length,key,sender,receiver)
|
||||
u_char *in, *out;
|
||||
u_long in_length;
|
||||
C_Block *key;
|
||||
struct sockaddr_in *sender, *receiver;
|
||||
{
|
||||
return krb_mk_safe (in,out,in_length,key,sender,receiver);
|
||||
}
|
||||
|
||||
long rd_safe_msg (in,length,key,sender,receiver,msg_data)
|
||||
u_char *in;
|
||||
u_long length;
|
||||
C_Block *key;
|
||||
struct sockaddr_in *sender, *receiver;
|
||||
MSG_DAT *msg_data;
|
||||
{
|
||||
return krb_rd_safe (in,length,key,sender,receiver,msg_data);
|
||||
}
|
||||
|
||||
long mk_appl_err_msg (out,code,string)
|
||||
u_char *out;
|
||||
long code;
|
||||
char *string;
|
||||
{
|
||||
return krb_mk_err (out,code,string);
|
||||
}
|
||||
|
||||
long rd_appl_err_msg (in,length,code,msg_data)
|
||||
u_char *in;
|
||||
u_long length;
|
||||
long *code;
|
||||
MSG_DAT *msg_data;
|
||||
{
|
||||
return krb_rd_err (in,length,code,msg_data);
|
||||
}
|
||||
|
||||
int get_in_tkt(user,instance,realm,service,sinstance,life,password)
|
||||
char *user, *instance, *realm, *service, *sinstance;
|
||||
int life;
|
||||
char *password;
|
||||
{
|
||||
return krb_get_pw_in_tkt(user,instance,realm,service,sinstance,
|
||||
life,password);
|
||||
}
|
||||
|
||||
int get_svc_in_tkt(user, instance, realm, service, sinstance, life, srvtab)
|
||||
char *user, *instance, *realm, *service, *sinstance;
|
||||
int life;
|
||||
char *srvtab;
|
||||
{
|
||||
return krb_get_svc_in_tkt(user, instance, realm, service, sinstance,
|
||||
life, srvtab);
|
||||
}
|
||||
|
||||
int get_pw_tkt(user,instance,realm,cpw)
|
||||
char *user;
|
||||
char *instance;
|
||||
char *realm;
|
||||
char *cpw;
|
||||
{
|
||||
return krb_get_pw_tkt(user,instance,realm,cpw);
|
||||
}
|
||||
|
||||
int
|
||||
get_krbrlm (r, n)
|
||||
char *r;
|
||||
int n;
|
||||
{
|
||||
return krb_get_lream(r,n);
|
||||
}
|
||||
|
||||
int
|
||||
krb_getrealm (host)
|
||||
{
|
||||
return krb_realmofhost(host);
|
||||
}
|
||||
|
||||
char *
|
||||
get_phost (host)
|
||||
char *host
|
||||
{
|
||||
return krb_get_phost(host);
|
||||
}
|
||||
|
||||
int
|
||||
get_krbhst (h, r, n)
|
||||
char *h;
|
||||
char *r;
|
||||
int n;
|
||||
{
|
||||
return krb_get_krbhst(h,r,n);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
struct ktext *create_death_packet(a_name)
|
||||
char *a_name;
|
||||
{
|
||||
return krb_create_death_packet(a_name);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
#if 0
|
||||
extern int krb_ck_repl ();
|
||||
|
||||
int check_replay ()
|
||||
{
|
||||
return krb_ck_repl ();
|
||||
}
|
||||
#endif
|
||||
#endif /* NCOMPAT */
|
||||
@@ -1,63 +0,0 @@
|
||||
.\" from: kuserok.3,v 4.1 89/01/23 11:11:49 jtkohl Exp $
|
||||
.\" $Id: kuserok.3,v 1.1.1.1 1994/09/30 14:50:07 csgr Exp $
|
||||
.\" Copyright 1989 by the Massachusetts Institute of Technology.
|
||||
.\"
|
||||
.\" For copying and distribution information,
|
||||
.\" please see the file <Copyright.MIT>.
|
||||
.\"
|
||||
.TH KUSEROK 3 "Kerberos Version 4.0" "MIT Project Athena"
|
||||
.SH NAME
|
||||
kuserok \- Kerberos version of ruserok
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.nj
|
||||
.ft B
|
||||
#include <kerberosIV/krb.h>
|
||||
.PP
|
||||
.ft B
|
||||
kuserok(kdata, localuser)
|
||||
AUTH_DAT *auth_data;
|
||||
char *localuser;
|
||||
.fi
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
.I kuserok
|
||||
determines whether a Kerberos principal described by the structure
|
||||
.I auth_data
|
||||
is authorized to login as user
|
||||
.I localuser
|
||||
according to the authorization file
|
||||
("~\fIlocaluser\fR/.klogin" by default). It returns 0 (zero) if authorized,
|
||||
1 (one) if not authorized.
|
||||
.PP
|
||||
If there is no account for
|
||||
.I localuser
|
||||
on the local machine, authorization is not granted.
|
||||
If there is no authorization file, and the Kerberos principal described
|
||||
by
|
||||
.I auth_data
|
||||
translates to
|
||||
.I localuser
|
||||
(using
|
||||
.IR krb_kntoln (3)),
|
||||
authorization is granted.
|
||||
If the authorization file
|
||||
can't be accessed, or the file is not owned by
|
||||
.IR localuser,
|
||||
authorization is denied. Otherwise, the file is searched for
|
||||
a matching principal name, instance, and realm. If a match is found,
|
||||
authorization is granted, else authorization is denied.
|
||||
.PP
|
||||
The file entries are in the format:
|
||||
.nf
|
||||
.in +5n
|
||||
name.instance@realm
|
||||
.in -5n
|
||||
.fi
|
||||
with one entry per line.
|
||||
.SH SEE ALSO
|
||||
kerberos(3), ruserok(3), krb_kntoln(3)
|
||||
.SH FILES
|
||||
.TP 20n
|
||||
~\fIlocaluser\fR/.klogin
|
||||
authorization list
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* kuserok: check if a kerberos principal has
|
||||
* access to a local account
|
||||
*
|
||||
* from: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $
|
||||
* $Id: kuserok.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: kuserok.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <krb.h>
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <strings.h>
|
||||
|
||||
#define OK 0
|
||||
#define NOTOK 1
|
||||
#define MAX_USERNAME 10
|
||||
|
||||
/*
|
||||
* Given a Kerberos principal "kdata", and a local username "luser",
|
||||
* determine whether user is authorized to login according to the
|
||||
* authorization file ("~luser/.klogin" by default). Returns OK
|
||||
* if authorized, NOTOK if not authorized.
|
||||
*
|
||||
* If there is no account for "luser" on the local machine, returns
|
||||
* NOTOK. If there is no authorization file, and the given Kerberos
|
||||
* name "kdata" translates to the same name as "luser" (using
|
||||
* krb_kntoln()), returns OK. Otherwise, if the authorization file
|
||||
* can't be accessed, returns NOTOK. Otherwise, the file is read for
|
||||
* a matching principal name, instance, and realm. If one is found,
|
||||
* returns OK, if none is found, returns NOTOK.
|
||||
*
|
||||
* The file entries are in the format:
|
||||
*
|
||||
* name.instance@realm
|
||||
*
|
||||
* one entry per line.
|
||||
*
|
||||
* The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin
|
||||
* file entries. See the file "kparse.c".
|
||||
*/
|
||||
|
||||
#ifdef ATHENA_COMPAT
|
||||
|
||||
#include <kparse.h>
|
||||
|
||||
/*
|
||||
* The parmtable defines the keywords we will recognize with their
|
||||
* default values, and keeps a pointer to the found value. The found
|
||||
* value should be filled in with strsave(), since FreeParameterSet()
|
||||
* will release memory for all non-NULL found strings.
|
||||
*
|
||||
*** NOTE WELL! ***
|
||||
*
|
||||
* The table below is very nice, but we cannot hard-code a default for the
|
||||
* realm: we have to get the realm via krb_get_lrealm(). Even though the
|
||||
* default shows as "from krb_get_lrealm, below", it gets changed in
|
||||
* kuserok to whatever krb_get_lrealm() tells us. That code assumes that
|
||||
* the realm will be the entry number in the table below, so if you
|
||||
* change the order of the entries below, you have to change the
|
||||
* #definition of REALM_SCRIPT to reflect it.
|
||||
*/
|
||||
#define REALM_SUBSCRIPT 1
|
||||
parmtable kparm[] = {
|
||||
|
||||
/* keyword default found value */
|
||||
{"user", "", (char *) NULL},
|
||||
{"realm", "see krb_get_lrealm, below", (char *) NULL},
|
||||
{"instance", "", (char *) NULL},
|
||||
};
|
||||
#define KPARMS kparm,PARMCOUNT(kparm)
|
||||
#endif ATHENA_COMPAT
|
||||
|
||||
kuserok(kdata, luser)
|
||||
AUTH_DAT *kdata;
|
||||
char *luser;
|
||||
{
|
||||
struct stat sbuf;
|
||||
struct passwd *pwd;
|
||||
char pbuf[MAXPATHLEN];
|
||||
int isok = NOTOK, rc;
|
||||
FILE *fp;
|
||||
char kuser[MAX_USERNAME];
|
||||
char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
|
||||
char linebuf[BUFSIZ];
|
||||
char *newline;
|
||||
int gobble;
|
||||
#ifdef ATHENA_COMPAT
|
||||
char local_realm[REALM_SZ];
|
||||
#endif ATHENA_COMPAT
|
||||
|
||||
/* no account => no access */
|
||||
if ((pwd = getpwnam(luser)) == NULL) {
|
||||
return(NOTOK);
|
||||
}
|
||||
(void) strcpy(pbuf, pwd->pw_dir);
|
||||
(void) strcat(pbuf, "/.klogin");
|
||||
|
||||
if (access(pbuf, F_OK)) { /* not accessible */
|
||||
/*
|
||||
* if he's trying to log in as himself, and there is no .klogin file,
|
||||
* let him. To find out, call
|
||||
* krb_kntoln to convert the triple in kdata to a name which we can
|
||||
* string compare.
|
||||
*/
|
||||
if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) {
|
||||
return(OK);
|
||||
}
|
||||
}
|
||||
/* open ~/.klogin */
|
||||
if ((fp = fopen(pbuf, "r")) == NULL) {
|
||||
return(NOTOK);
|
||||
}
|
||||
/*
|
||||
* security: if the user does not own his own .klogin file,
|
||||
* do not grant access
|
||||
*/
|
||||
if (fstat(fileno(fp), &sbuf)) {
|
||||
fclose(fp);
|
||||
return(NOTOK);
|
||||
}
|
||||
if (sbuf.st_uid != pwd->pw_uid) {
|
||||
fclose(fp);
|
||||
return(NOTOK);
|
||||
}
|
||||
|
||||
#ifdef ATHENA_COMPAT
|
||||
/* Accept old-style .klogin files */
|
||||
|
||||
/*
|
||||
* change the default realm from the hard-coded value to the
|
||||
* accepted realm that Kerberos specifies.
|
||||
*/
|
||||
rc = krb_get_lrealm(local_realm, 1);
|
||||
if (rc == KSUCCESS)
|
||||
kparm[REALM_SUBSCRIPT].defvalue = local_realm;
|
||||
else
|
||||
return (rc);
|
||||
|
||||
/* check each line */
|
||||
while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) {
|
||||
switch (rc) {
|
||||
case PS_BAD_KEYWORD:
|
||||
case PS_SYNTAX:
|
||||
while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n'));
|
||||
break;
|
||||
|
||||
case PS_OKAY:
|
||||
isok = (ParmCompare(KPARMS, "user", kdata->pname) ||
|
||||
ParmCompare(KPARMS, "instance", kdata->pinst) ||
|
||||
ParmCompare(KPARMS, "realm", kdata->prealm));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
FreeParameterSet(kparm, PARMCOUNT(kparm));
|
||||
}
|
||||
/* reset the stream for parsing new-style names, if necessary */
|
||||
rewind(fp);
|
||||
#endif ATHENA_COMPAT
|
||||
|
||||
/* check each line */
|
||||
while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
|
||||
/* null-terminate the input string */
|
||||
linebuf[BUFSIZ-1] = '\0';
|
||||
newline = NULL;
|
||||
/* nuke the newline if it exists */
|
||||
if (newline = index(linebuf, '\n'))
|
||||
*newline = '\0';
|
||||
rc = kname_parse(principal, inst, realm, linebuf);
|
||||
if (rc == KSUCCESS) {
|
||||
isok = (strncmp(kdata->pname, principal, ANAME_SZ) ||
|
||||
strncmp(kdata->pinst, inst, INST_SZ) ||
|
||||
strncmp(kdata->prealm, realm, REALM_SZ));
|
||||
}
|
||||
/* clean up the rest of the line if necessary */
|
||||
if (!newline)
|
||||
while (((gobble = getc(fp)) != EOF) && gobble != '\n');
|
||||
}
|
||||
fclose(fp);
|
||||
return(isok);
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: log.c,v 4.7 88/12/01 14:15:14 jtkohl Exp $
|
||||
* $Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: log.c,v 1.2 1994/07/19 19:25:53 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
#include <klog.h>
|
||||
|
||||
static char *log_name = KRBLOG;
|
||||
static is_open;
|
||||
|
||||
/*
|
||||
* This file contains three logging routines: set_logfile()
|
||||
* to determine the file that log entries should be written to;
|
||||
* and log() and new_log() to write log entries to the file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* log() is used to add entries to the logfile (see set_logfile()
|
||||
* below). Note that it is probably not portable since it makes
|
||||
* assumptions about what the compiler will do when it is called
|
||||
* with less than the correct number of arguments which is the
|
||||
* way it is usually called.
|
||||
*
|
||||
* The log entry consists of a timestamp and the given arguments
|
||||
* printed according to the given "format".
|
||||
*
|
||||
* The log file is opened and closed for each log entry.
|
||||
*
|
||||
* The return value is undefined.
|
||||
*/
|
||||
|
||||
__BEGIN_DECLS
|
||||
char *month_sname __P((int));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*VARARGS1 */
|
||||
void log(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0)
|
||||
char *format;
|
||||
int a1,a2,a3,a4,a5,a6,a7,a8,a9,a0;
|
||||
{
|
||||
FILE *logfile, *fopen();
|
||||
long time(),now;
|
||||
struct tm *tm;
|
||||
|
||||
if ((logfile = fopen(log_name,"a")) == NULL)
|
||||
return;
|
||||
|
||||
(void) time(&now);
|
||||
tm = localtime(&now);
|
||||
|
||||
fprintf(logfile,"%2d-%s-%02d %02d:%02d:%02d ",tm->tm_mday,
|
||||
month_sname(tm->tm_mon + 1),tm->tm_year,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
fprintf(logfile,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0);
|
||||
fprintf(logfile,"\n");
|
||||
(void) fclose(logfile);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* set_logfile() changes the name of the file to which
|
||||
* messages are logged. If set_logfile() is not called,
|
||||
* the logfile defaults to KRBLOG, defined in "krb.h".
|
||||
*/
|
||||
|
||||
set_logfile(filename)
|
||||
char *filename;
|
||||
{
|
||||
log_name = filename;
|
||||
is_open = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* new_log() appends a log entry containing the give time "t" and the
|
||||
* string "string" to the logfile (see set_logfile() above). The file
|
||||
* is opened once and left open. The routine returns 1 on failure, 0
|
||||
* on success.
|
||||
*/
|
||||
|
||||
new_log(t,string)
|
||||
long t;
|
||||
char *string;
|
||||
{
|
||||
static FILE *logfile;
|
||||
|
||||
long time();
|
||||
struct tm *tm;
|
||||
|
||||
if (!is_open) {
|
||||
if ((logfile = fopen(log_name,"a")) == NULL) return(1);
|
||||
is_open = 1;
|
||||
}
|
||||
|
||||
if (t) {
|
||||
tm = localtime(&t);
|
||||
|
||||
fprintf(logfile,"\n%2d-%s-%02d %02d:%02d:%02d %s",tm->tm_mday,
|
||||
month_sname(tm->tm_mon + 1),tm->tm_year,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec, string);
|
||||
}
|
||||
else {
|
||||
fprintf(logfile,"\n%20s%s","",string);
|
||||
}
|
||||
|
||||
(void) fflush(logfile);
|
||||
return(0);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: mk_err.c,v 4.4 88/11/15 16:33:36 jtkohl Exp $
|
||||
* $Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: mk_err.c,v 1.2 1994/07/19 19:25:54 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* This routine creates a general purpose error reply message. It
|
||||
* doesn't use KTEXT because application protocol may have long
|
||||
* messages, and may want this part of buffer contiguous to other
|
||||
* stuff.
|
||||
*
|
||||
* The error reply is built in "p", using the error code "e" and
|
||||
* error text "e_string" given. The length of the error reply is
|
||||
* returned.
|
||||
*
|
||||
* The error reply is in the following format:
|
||||
*
|
||||
* unsigned char KRB_PROT_VERSION protocol version no.
|
||||
* unsigned char AUTH_MSG_APPL_ERR message type
|
||||
* (least significant
|
||||
* bit of above) HOST_BYTE_ORDER local byte order
|
||||
* 4 bytes e given error code
|
||||
* string e_string given error text
|
||||
*/
|
||||
|
||||
long krb_mk_err(p,e,e_string)
|
||||
u_char *p; /* Where to build error packet */
|
||||
long e; /* Error code */
|
||||
char *e_string; /* Text of error */
|
||||
{
|
||||
u_char *start;
|
||||
|
||||
start = p;
|
||||
|
||||
/* Create fixed part of packet */
|
||||
*p++ = (unsigned char) KRB_PROT_VERSION;
|
||||
*p = (unsigned char) AUTH_MSG_APPL_ERR;
|
||||
*p++ |= HOST_BYTE_ORDER;
|
||||
|
||||
/* Add the basic info */
|
||||
bcopy((char *)&e,(char *)p,4); /* err code */
|
||||
p += sizeof(e);
|
||||
(void) strcpy((char *)p,e_string); /* err text */
|
||||
p += strlen(e_string);
|
||||
|
||||
/* And return the length */
|
||||
return p-start;
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* This routine constructs a Kerberos 'private msg', i.e.
|
||||
* cryptographically sealed with a private session key.
|
||||
*
|
||||
* Note-- bcopy is used to avoid alignment problems on IBM RT.
|
||||
*
|
||||
* Note-- It's too bad that it did a long int compare on the RT before.
|
||||
*
|
||||
* Returns either < 0 ===> error, or resulting size of message
|
||||
*
|
||||
* Steve Miller Project Athena MIT/DEC
|
||||
*
|
||||
* from: mk_priv.c,v 4.13 89/03/22 14:48:59 jtkohl Exp $
|
||||
* $Id: mk_priv.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: mk_priv.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
/* system include files */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* application include files */
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include "lsb_addr_comp.h"
|
||||
|
||||
extern char *errmsg();
|
||||
extern int errno;
|
||||
extern int krb_debug;
|
||||
|
||||
/* static storage */
|
||||
|
||||
|
||||
static u_long c_length;
|
||||
static struct timeval msg_time;
|
||||
static u_char msg_time_5ms;
|
||||
static long msg_time_sec;
|
||||
|
||||
/*
|
||||
* krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes
|
||||
* some user data "in" of "length" bytes and creates a packet in "out"
|
||||
* consisting of the user data, a timestamp, and the sender's network
|
||||
* address.
|
||||
#ifndef NOENCRYTION
|
||||
* The packet is encrypted by pcbc_encrypt(), using the given
|
||||
* "key" and "schedule".
|
||||
#endif
|
||||
* The length of the resulting packet "out" is
|
||||
* returned.
|
||||
*
|
||||
* It is similar to krb_mk_safe() except for the additional key
|
||||
* schedule argument "schedule" and the fact that the data is encrypted
|
||||
* rather than appended with a checksum. Also, the protocol version
|
||||
* number is "private_msg_ver", defined in krb_rd_priv.c, rather than
|
||||
* KRB_PROT_VERSION, defined in "krb.h".
|
||||
*
|
||||
* The "out" packet consists of:
|
||||
*
|
||||
* Size Variable Field
|
||||
* ---- -------- -----
|
||||
*
|
||||
* 1 byte private_msg_ver protocol version number
|
||||
* 1 byte AUTH_MSG_PRIVATE | message type plus local
|
||||
* HOST_BYTE_ORDER byte order in low bit
|
||||
*
|
||||
* 4 bytes c_length length of data
|
||||
#ifndef NOENCRYPT
|
||||
* we encrypt from here with pcbc_encrypt
|
||||
#endif
|
||||
*
|
||||
* 4 bytes length length of user data
|
||||
* length in user data
|
||||
* 1 byte msg_time_5ms timestamp milliseconds
|
||||
* 4 bytes sender->sin.addr.s_addr sender's IP address
|
||||
*
|
||||
* 4 bytes msg_time_sec or timestamp seconds with
|
||||
* -msg_time_sec direction in sign bit
|
||||
*
|
||||
* 0<=n<=7 bytes pad to 8 byte multiple zeroes
|
||||
*/
|
||||
|
||||
long krb_mk_priv(in,out,length,schedule,key,sender,receiver)
|
||||
u_char *in; /* application data */
|
||||
u_char *out; /* put msg here, leave room for
|
||||
* header! breaks if in and out
|
||||
* (header stuff) overlap */
|
||||
u_long length; /* of in data */
|
||||
Key_schedule schedule; /* precomputed key schedule */
|
||||
C_Block key; /* encryption key for seed and ivec */
|
||||
struct sockaddr_in *sender; /* sender address */
|
||||
struct sockaddr_in *receiver; /* receiver address */
|
||||
{
|
||||
register u_char *p,*q;
|
||||
static u_char *c_length_ptr;
|
||||
extern int private_msg_ver; /* in krb_rd_priv.c */
|
||||
|
||||
/*
|
||||
* get the current time to use instead of a sequence #, since
|
||||
* process lifetime may be shorter than the lifetime of a session
|
||||
* key.
|
||||
*/
|
||||
if (gettimeofday(&msg_time,(struct timezone *)0)) {
|
||||
return -1;
|
||||
}
|
||||
msg_time_sec = (long) msg_time.tv_sec;
|
||||
msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
|
||||
|
||||
p = out;
|
||||
|
||||
*p++ = private_msg_ver;
|
||||
*p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
|
||||
|
||||
/* calculate cipher length */
|
||||
c_length_ptr = p;
|
||||
p += sizeof(c_length);
|
||||
|
||||
q = p;
|
||||
|
||||
/* stuff input length */
|
||||
bcopy((char *)&length,(char *)p,sizeof(length));
|
||||
p += sizeof(length);
|
||||
|
||||
#ifdef NOENCRYPTION
|
||||
/* make all the stuff contiguous for checksum */
|
||||
#else
|
||||
/* make all the stuff contiguous for checksum and encryption */
|
||||
#endif
|
||||
bcopy((char *)in,(char *)p,(int) length);
|
||||
p += length;
|
||||
|
||||
/* stuff time 5ms */
|
||||
bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
|
||||
p += sizeof(msg_time_5ms);
|
||||
|
||||
/* stuff source address */
|
||||
bcopy((char *)&sender->sin_addr.s_addr,(char *)p,
|
||||
sizeof(sender->sin_addr.s_addr));
|
||||
p += sizeof(sender->sin_addr.s_addr);
|
||||
|
||||
/*
|
||||
* direction bit is the sign bit of the timestamp. Ok
|
||||
* until 2038??
|
||||
*/
|
||||
/* For compatibility with broken old code, compares are done in VAX
|
||||
byte order (LSBFIRST) */
|
||||
if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
|
||||
receiver->sin_addr.s_addr)==-1)
|
||||
msg_time_sec = -msg_time_sec;
|
||||
else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
|
||||
receiver->sin_addr.s_addr)==0)
|
||||
if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
|
||||
msg_time_sec = -msg_time_sec;
|
||||
/* stuff time sec */
|
||||
bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
|
||||
p += sizeof(msg_time_sec);
|
||||
|
||||
/*
|
||||
* All that for one tiny bit! Heaven help those that talk to
|
||||
* themselves.
|
||||
*/
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* calculate the checksum of the length, address, sequence, and
|
||||
* inp data
|
||||
*/
|
||||
cksum = quad_cksum(q,NULL,p-q,0,key);
|
||||
if (krb_debug)
|
||||
printf("\ncksum = %u",cksum);
|
||||
/* stuff checksum */
|
||||
bcopy((char *) &cksum,(char *) p,sizeof(cksum));
|
||||
p += sizeof(cksum);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* All the data have been assembled, compute length
|
||||
*/
|
||||
|
||||
c_length = p - q;
|
||||
c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) *
|
||||
sizeof(C_Block);
|
||||
/* stuff the length */
|
||||
bcopy((char *) &c_length,(char *)c_length_ptr,sizeof(c_length));
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)(p-q),schedule,key,ENCRYPT);
|
||||
#endif /* NOENCRYPTION */
|
||||
|
||||
return (q - out + c_length); /* resulting size */
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: der: mk_req.c,v 4.17 89/07/07 15:20:35 jtkohl Exp $
|
||||
* $Id: mk_req.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: mk_req.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <des.h>
|
||||
#include <sys/time.h>
|
||||
#include <strings.h>
|
||||
|
||||
extern int krb_ap_req_debug;
|
||||
static struct timeval tv_local = { 0, 0 };
|
||||
static int lifetime = DEFAULT_TKT_LIFE;
|
||||
|
||||
/*
|
||||
* krb_mk_req takes a text structure in which an authenticator is to
|
||||
* be built, the name of a service, an instance, a realm,
|
||||
* and a checksum. It then retrieves a ticket for
|
||||
* the desired service and creates an authenticator in the text
|
||||
* structure passed as the first argument. krb_mk_req returns
|
||||
* KSUCCESS on success and a Kerberos error code on failure.
|
||||
*
|
||||
* The peer procedure on the other end is krb_rd_req. When making
|
||||
* any changes to this routine it is important to make corresponding
|
||||
* changes to krb_rd_req.
|
||||
*
|
||||
* The authenticator consists of the following:
|
||||
*
|
||||
* authent->dat
|
||||
*
|
||||
* unsigned char KRB_PROT_VERSION protocol version no.
|
||||
* unsigned char AUTH_MSG_APPL_REQUEST message type
|
||||
* (least significant
|
||||
* bit of above) HOST_BYTE_ORDER local byte ordering
|
||||
* unsigned char kvno from ticket server's key version
|
||||
* string realm server's realm
|
||||
* unsigned char tl ticket length
|
||||
* unsigned char idl request id length
|
||||
* text ticket->dat ticket for server
|
||||
* text req_id->dat request id
|
||||
*
|
||||
* The ticket information is retrieved from the ticket cache or
|
||||
* fetched from Kerberos. The request id (called the "authenticator"
|
||||
* in the papers on Kerberos) contains the following:
|
||||
*
|
||||
* req_id->dat
|
||||
*
|
||||
* string cr.pname {name, instance, and
|
||||
* string cr.pinst realm of principal
|
||||
* string myrealm making this request}
|
||||
* 4 bytes checksum checksum argument given
|
||||
* unsigned char tv_local.tf_usec time (milliseconds)
|
||||
* 4 bytes tv_local.tv_sec time (seconds)
|
||||
*
|
||||
* req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
|
||||
* all rounded up to multiple of 8.
|
||||
*/
|
||||
|
||||
krb_mk_req(authent,service,instance,realm,checksum)
|
||||
register KTEXT authent; /* Place to build the authenticator */
|
||||
char *service; /* Name of the service */
|
||||
char *instance; /* Service instance */
|
||||
char *realm; /* Authentication domain of service */
|
||||
long checksum; /* Checksum of data (optional) */
|
||||
{
|
||||
static KTEXT_ST req_st; /* Temp storage for req id */
|
||||
register KTEXT req_id = &req_st;
|
||||
unsigned char *v = authent->dat; /* Prot version number */
|
||||
unsigned char *t = (authent->dat+1); /* Message type */
|
||||
unsigned char *kv = (authent->dat+2); /* Key version no */
|
||||
unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */
|
||||
unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */
|
||||
CREDENTIALS cr; /* Credentials used by retr */
|
||||
register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
|
||||
int retval; /* Returned by krb_get_cred */
|
||||
static Key_schedule key_s;
|
||||
char myrealm[REALM_SZ];
|
||||
|
||||
/* The fixed parts of the authenticator */
|
||||
*v = (unsigned char) KRB_PROT_VERSION;
|
||||
*t = (unsigned char) AUTH_MSG_APPL_REQUEST;
|
||||
*t |= HOST_BYTE_ORDER;
|
||||
|
||||
/* Get the ticket and move it into the authenticator */
|
||||
if (krb_ap_req_debug)
|
||||
printf("Realm: %s\n",realm);
|
||||
/*
|
||||
* Determine realm of these tickets. We will send this to the
|
||||
* KDC from which we are requesting tickets so it knows what to
|
||||
* with our session key.
|
||||
*/
|
||||
if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
|
||||
return(retval);
|
||||
|
||||
retval = krb_get_cred(service,instance,realm,&cr);
|
||||
|
||||
if (retval == RET_NOTKT) {
|
||||
if (retval = get_ad_tkt(service,instance,realm,lifetime))
|
||||
return(retval);
|
||||
if (retval = krb_get_cred(service,instance,realm,&cr))
|
||||
return(retval);
|
||||
}
|
||||
|
||||
if (retval != KSUCCESS) return (retval);
|
||||
|
||||
if (krb_ap_req_debug)
|
||||
printf("%s %s %s %s %s\n", service, instance, realm,
|
||||
cr.pname, cr.pinst);
|
||||
*kv = (unsigned char) cr.kvno;
|
||||
(void) strcpy((char *)(authent->dat+3),realm);
|
||||
*tl = (unsigned char) ticket->length;
|
||||
bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)),
|
||||
ticket->length);
|
||||
authent->length = 6 + strlen(realm) + ticket->length;
|
||||
if (krb_ap_req_debug)
|
||||
printf("Ticket->length = %d\n",ticket->length);
|
||||
if (krb_ap_req_debug)
|
||||
printf("Issue date: %d\n",cr.issue_date);
|
||||
|
||||
/* Build request id */
|
||||
(void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
|
||||
req_id->length = strlen(cr.pname)+1;
|
||||
/* Principal's instance */
|
||||
(void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
|
||||
req_id->length += strlen(cr.pinst)+1;
|
||||
/* Authentication domain */
|
||||
(void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
|
||||
req_id->length += strlen(myrealm)+1;
|
||||
/* Checksum */
|
||||
bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4);
|
||||
req_id->length += 4;
|
||||
|
||||
/* Fill in the times on the request id */
|
||||
(void) gettimeofday(&tv_local,(struct timezone *) 0);
|
||||
*(req_id->dat+(req_id->length)++) =
|
||||
(unsigned char) tv_local.tv_usec;
|
||||
/* Time (coarse) */
|
||||
bcopy((char *)&(tv_local.tv_sec),
|
||||
(char *)(req_id->dat+req_id->length), 4);
|
||||
req_id->length += 4;
|
||||
|
||||
/* Fill to a multiple of 8 bytes for DES */
|
||||
req_id->length = ((req_id->length+7)/8)*8;
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(cr.session,key_s);
|
||||
pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
|
||||
(long)req_id->length,key_s,cr.session,ENCRYPT);
|
||||
bzero((char *) key_s, sizeof(key_s));
|
||||
#endif /* NOENCRYPTION */
|
||||
|
||||
/* Copy it into the authenticator */
|
||||
bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length),
|
||||
req_id->length);
|
||||
authent->length += req_id->length;
|
||||
/* And set the id length */
|
||||
*idl = (unsigned char) req_id->length;
|
||||
/* clean up */
|
||||
bzero((char *)req_id, sizeof(*req_id));
|
||||
|
||||
if (krb_ap_req_debug)
|
||||
printf("Authent->length = %d\n",authent->length);
|
||||
if (krb_ap_req_debug)
|
||||
printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl);
|
||||
|
||||
return(KSUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* krb_set_lifetime sets the default lifetime for additional tickets
|
||||
* obtained via krb_mk_req().
|
||||
*
|
||||
* It returns the previous value of the default lifetime.
|
||||
*/
|
||||
|
||||
int
|
||||
krb_set_lifetime(newval)
|
||||
int newval;
|
||||
{
|
||||
int olife = lifetime;
|
||||
|
||||
lifetime = newval;
|
||||
return(olife);
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* This routine constructs a Kerberos 'safe msg', i.e. authenticated
|
||||
* using a private session key to seed a checksum. Msg is NOT
|
||||
* encrypted.
|
||||
*
|
||||
* Note-- bcopy is used to avoid alignment problems on IBM RT
|
||||
*
|
||||
* Returns either <0 ===> error, or resulting size of message
|
||||
*
|
||||
* Steve Miller Project Athena MIT/DEC
|
||||
*
|
||||
* from: mk_safe.c,v 4.12 89/03/22 14:50:49 jtkohl Exp $
|
||||
* $Id: mk_safe.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: mk_safe.c,v 1.1.1.1 1994/09/30 14:50:02 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
/* system include files */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* application include files */
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include "lsb_addr_comp.h"
|
||||
|
||||
extern char *errmsg();
|
||||
extern int errno;
|
||||
extern int krb_debug;
|
||||
|
||||
/* static storage */
|
||||
|
||||
static u_long cksum;
|
||||
static C_Block big_cksum[2];
|
||||
static struct timeval msg_time;
|
||||
static u_char msg_time_5ms;
|
||||
static long msg_time_sec;
|
||||
|
||||
/*
|
||||
* krb_mk_safe() constructs an AUTH_MSG_SAFE message. It takes some
|
||||
* user data "in" of "length" bytes and creates a packet in "out"
|
||||
* consisting of the user data, a timestamp, and the sender's network
|
||||
* address, followed by a checksum computed on the above, using the
|
||||
* given "key". The length of the resulting packet is returned.
|
||||
*
|
||||
* The "out" packet consists of:
|
||||
*
|
||||
* Size Variable Field
|
||||
* ---- -------- -----
|
||||
*
|
||||
* 1 byte KRB_PROT_VERSION protocol version number
|
||||
* 1 byte AUTH_MSG_SAFE | message type plus local
|
||||
* HOST_BYTE_ORDER byte order in low bit
|
||||
*
|
||||
* ===================== begin checksum ================================
|
||||
*
|
||||
* 4 bytes length length of user data
|
||||
* length in user data
|
||||
* 1 byte msg_time_5ms timestamp milliseconds
|
||||
* 4 bytes sender->sin.addr.s_addr sender's IP address
|
||||
*
|
||||
* 4 bytes msg_time_sec or timestamp seconds with
|
||||
* -msg_time_sec direction in sign bit
|
||||
*
|
||||
* ======================= end checksum ================================
|
||||
*
|
||||
* 16 bytes big_cksum quadratic checksum of
|
||||
* above using "key"
|
||||
*/
|
||||
|
||||
long krb_mk_safe(in,out,length,key,sender,receiver)
|
||||
u_char *in; /* application data */
|
||||
u_char *out; /*
|
||||
* put msg here, leave room for header!
|
||||
* breaks if in and out (header stuff)
|
||||
* overlap
|
||||
*/
|
||||
u_long length; /* of in data */
|
||||
C_Block *key; /* encryption key for seed and ivec */
|
||||
struct sockaddr_in *sender; /* sender address */
|
||||
struct sockaddr_in *receiver; /* receiver address */
|
||||
{
|
||||
register u_char *p,*q;
|
||||
|
||||
/*
|
||||
* get the current time to use instead of a sequence #, since
|
||||
* process lifetime may be shorter than the lifetime of a session
|
||||
* key.
|
||||
*/
|
||||
if (gettimeofday(&msg_time,(struct timezone *)0)) {
|
||||
return -1;
|
||||
}
|
||||
msg_time_sec = (long) msg_time.tv_sec;
|
||||
msg_time_5ms = msg_time.tv_usec/5000; /* 5ms quanta */
|
||||
|
||||
p = out;
|
||||
|
||||
*p++ = KRB_PROT_VERSION;
|
||||
*p++ = AUTH_MSG_SAFE | HOST_BYTE_ORDER;
|
||||
|
||||
q = p; /* start for checksum stuff */
|
||||
/* stuff input length */
|
||||
bcopy((char *)&length,(char *)p,sizeof(length));
|
||||
p += sizeof(length);
|
||||
|
||||
/* make all the stuff contiguous for checksum */
|
||||
bcopy((char *)in,(char *)p,(int) length);
|
||||
p += length;
|
||||
|
||||
/* stuff time 5ms */
|
||||
bcopy((char *)&msg_time_5ms,(char *)p,sizeof(msg_time_5ms));
|
||||
p += sizeof(msg_time_5ms);
|
||||
|
||||
/* stuff source address */
|
||||
bcopy((char *) &sender->sin_addr.s_addr,(char *)p,
|
||||
sizeof(sender->sin_addr.s_addr));
|
||||
p += sizeof(sender->sin_addr.s_addr);
|
||||
|
||||
/*
|
||||
* direction bit is the sign bit of the timestamp. Ok until
|
||||
* 2038??
|
||||
*/
|
||||
/* For compatibility with broken old code, compares are done in VAX
|
||||
byte order (LSBFIRST) */
|
||||
if (lsb_net_ulong_less(sender->sin_addr.s_addr, /* src < recv */
|
||||
receiver->sin_addr.s_addr)==-1)
|
||||
msg_time_sec = -msg_time_sec;
|
||||
else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
|
||||
receiver->sin_addr.s_addr)==0)
|
||||
if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port) == -1)
|
||||
msg_time_sec = -msg_time_sec;
|
||||
/*
|
||||
* all that for one tiny bit! Heaven help those that talk to
|
||||
* themselves.
|
||||
*/
|
||||
|
||||
/* stuff time sec */
|
||||
bcopy((char *)&msg_time_sec,(char *)p,sizeof(msg_time_sec));
|
||||
p += sizeof(msg_time_sec);
|
||||
|
||||
#ifdef NOENCRYPTION
|
||||
cksum = 0;
|
||||
bzero(big_cksum, sizeof(big_cksum));
|
||||
#else
|
||||
cksum=quad_cksum(q,big_cksum,p-q,2,key);
|
||||
#endif
|
||||
if (krb_debug)
|
||||
printf("\ncksum = %u",cksum);
|
||||
|
||||
/* stuff checksum */
|
||||
bcopy((char *)big_cksum,(char *)p,sizeof(big_cksum));
|
||||
p += sizeof(big_cksum);
|
||||
|
||||
return ((long)(p - out)); /* resulting size */
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: month_sname.c,v 4.4 88/11/15 16:39:32 jtkohl Exp $
|
||||
* $Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: month_sname.c,v 1.2 1994/07/19 19:26:00 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
|
||||
/*
|
||||
* Given an integer 1-12, month_sname() returns a string
|
||||
* containing the first three letters of the corresponding
|
||||
* month. Returns 0 if the argument is out of range.
|
||||
*/
|
||||
|
||||
char *month_sname(n)
|
||||
int n;
|
||||
{
|
||||
static char *name[] = {
|
||||
"Jan","Feb","Mar","Apr","May","Jun",
|
||||
"Jul","Aug","Sep","Oct","Nov","Dec"
|
||||
};
|
||||
return((n < 1 || n > 12) ? 0 : name [n-1]);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: netread.c,v 4.1 88/11/15 16:47:21 jtkohl Exp $
|
||||
* $Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: netread.c,v 1.2 1994/07/19 19:26:03 g89r4222 Exp $";
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
* krb_net_read() reads from the file descriptor "fd" to the buffer
|
||||
* "buf", until either 1) "len" bytes have been read or 2) cannot
|
||||
* read anymore from "fd". It returns the number of bytes read
|
||||
* or a read() error. (The calling interface is identical to
|
||||
* read(2).)
|
||||
*
|
||||
* XXX must not use non-blocking I/O
|
||||
*/
|
||||
|
||||
int
|
||||
krb_net_read(fd, buf, len)
|
||||
int fd;
|
||||
register char *buf;
|
||||
register int len;
|
||||
{
|
||||
int cc, len2 = 0;
|
||||
|
||||
do {
|
||||
cc = read(fd, buf, len);
|
||||
if (cc < 0)
|
||||
return(cc); /* errno is already set */
|
||||
else if (cc == 0) {
|
||||
return(len2);
|
||||
} else {
|
||||
buf += cc;
|
||||
len2 += cc;
|
||||
len -= cc;
|
||||
}
|
||||
} while (len > 0);
|
||||
return(len2);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: netwrite.c,v 4.1 88/11/15 16:48:58 jtkohl Exp $";
|
||||
* $Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: netwrite.c,v 1.2 1994/07/19 19:26:04 g89r4222 Exp $";
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
* krb_net_write() writes "len" bytes from "buf" to the file
|
||||
* descriptor "fd". It returns the number of bytes written or
|
||||
* a write() error. (The calling interface is identical to
|
||||
* write(2).)
|
||||
*
|
||||
* XXX must not use non-blocking I/O
|
||||
*/
|
||||
|
||||
int
|
||||
krb_net_write(fd, buf, len)
|
||||
int fd;
|
||||
register char *buf;
|
||||
int len;
|
||||
{
|
||||
int cc;
|
||||
register int wrlen = len;
|
||||
do {
|
||||
cc = write(fd, buf, wrlen);
|
||||
if (cc < 0)
|
||||
return(cc);
|
||||
else {
|
||||
buf += cc;
|
||||
wrlen -= cc;
|
||||
}
|
||||
} while (wrlen > 0);
|
||||
return(len);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* form: one.c,v 4.1 88/11/15 16:51:41 jtkohl Exp $
|
||||
* $Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: one.c,v 1.2 1994/07/19 19:26:05 g89r4222 Exp $";
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
* definition of variable set to 1.
|
||||
* used in krb_conf.h to determine host byte order.
|
||||
*/
|
||||
|
||||
int krbONE = 1;
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: pkt_cipher.c,v 4.8 89/01/13 17:46:14 steiner Exp $
|
||||
* $Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: pkt_cipher.c,v 1.2 1994/07/19 19:26:07 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
|
||||
|
||||
/*
|
||||
* This routine takes a reply packet from the Kerberos ticket-granting
|
||||
* service and returns a pointer to the beginning of the ciphertext in it.
|
||||
*
|
||||
* See "prot.h" for packet format.
|
||||
*/
|
||||
|
||||
KTEXT
|
||||
pkt_cipher(packet)
|
||||
KTEXT packet;
|
||||
{
|
||||
unsigned char *ptr = pkt_a_realm(packet) + 6
|
||||
+ strlen((char *)pkt_a_realm(packet));
|
||||
/* Skip a few more fields */
|
||||
ptr += 3 + 4; /* add 4 for exp_date */
|
||||
|
||||
/* And return the pointer */
|
||||
return((KTEXT) ptr);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: pkt_clen.c,v 4.7 88/11/15 16:56:36 jtkohl Exp $
|
||||
* $Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: pkt_clen.c,v 1.2 1994/07/19 19:26:09 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
|
||||
extern int krb_debug;
|
||||
extern int swap_bytes;
|
||||
|
||||
/*
|
||||
* Given a pointer to an AUTH_MSG_KDC_REPLY packet, return the length of
|
||||
* its ciphertext portion. The external variable "swap_bytes" is assumed
|
||||
* to have been set to indicate whether or not the packet is in local
|
||||
* byte order. pkt_clen() takes this into account when reading the
|
||||
* ciphertext length out of the packet.
|
||||
*/
|
||||
|
||||
pkt_clen(pkt)
|
||||
KTEXT pkt;
|
||||
{
|
||||
static unsigned short temp,temp2;
|
||||
int clen = 0;
|
||||
|
||||
/* Start of ticket list */
|
||||
unsigned char *ptr = pkt_a_realm(pkt) + 10
|
||||
+ strlen((char *)pkt_a_realm(pkt));
|
||||
|
||||
/* Finally the length */
|
||||
bcopy((char *)(++ptr),(char *)&temp,2); /* alignment */
|
||||
if (swap_bytes) {
|
||||
/* assume a short is 2 bytes?? */
|
||||
swab((char *)&temp,(char *)&temp2,2);
|
||||
temp = temp2;
|
||||
}
|
||||
|
||||
clen = (int) temp;
|
||||
|
||||
if (krb_debug)
|
||||
printf("Clen is %d\n",clen);
|
||||
return(clen);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* This routine dissects a a Kerberos 'safe msg',
|
||||
* checking its integrity, and returning a pointer to the application
|
||||
* data contained and its length.
|
||||
*
|
||||
* Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
|
||||
*
|
||||
* Steve Miller Project Athena MIT/DEC
|
||||
*
|
||||
* from: rd_err.c,v 4.5 89/01/13 17:26:38 steiner Exp $
|
||||
* $Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: rd_err.c,v 1.2 1994/07/19 19:26:10 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
/* system include files */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* application include files */
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
|
||||
/*
|
||||
* Given an AUTH_MSG_APPL_ERR message, "in" and its length "in_length",
|
||||
* return the error code from the message in "code" and the text in
|
||||
* "m_data" as follows:
|
||||
*
|
||||
* m_data->app_data points to the error text
|
||||
* m_data->app_length points to the length of the error text
|
||||
*
|
||||
* If all goes well, return RD_AP_OK. If the version number
|
||||
* is wrong, return RD_AP_VERSION, and if it's not an AUTH_MSG_APPL_ERR
|
||||
* type message, return RD_AP_MSG_TYPE.
|
||||
*
|
||||
* The AUTH_MSG_APPL_ERR message format can be found in mk_err.c
|
||||
*/
|
||||
|
||||
int
|
||||
krb_rd_err(in,in_length,code,m_data)
|
||||
u_char *in; /* pointer to the msg received */
|
||||
u_long in_length; /* of in msg */
|
||||
long *code; /* received error code */
|
||||
MSG_DAT *m_data;
|
||||
{
|
||||
register u_char *p;
|
||||
int swap_bytes = 0;
|
||||
p = in; /* beginning of message */
|
||||
|
||||
if (*p++ != KRB_PROT_VERSION)
|
||||
return(RD_AP_VERSION);
|
||||
if (((*p) & ~1) != AUTH_MSG_APPL_ERR)
|
||||
return(RD_AP_MSG_TYPE);
|
||||
if ((*p++ & 1) != HOST_BYTE_ORDER)
|
||||
swap_bytes++;
|
||||
|
||||
/* safely get code */
|
||||
bcopy((char *)p,(char *)code,sizeof(*code));
|
||||
if (swap_bytes)
|
||||
swap_u_long(*code);
|
||||
p += sizeof(*code); /* skip over */
|
||||
|
||||
m_data->app_data = p; /* we're now at the error text
|
||||
* message */
|
||||
m_data->app_length = in_length;
|
||||
|
||||
return(RD_AP_OK); /* OK == 0 */
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* This routine dissects a a Kerberos 'private msg', decrypting it,
|
||||
* checking its integrity, and returning a pointer to the application
|
||||
* data contained and its length.
|
||||
*
|
||||
* Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If
|
||||
* the return value is RD_AP_TIME, then either the times are too far
|
||||
* out of synch, OR the packet was modified.
|
||||
*
|
||||
* Steve Miller Project Athena MIT/DEC
|
||||
*
|
||||
* from: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $
|
||||
* $Id: rd_priv.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[]=
|
||||
"$Id: rd_priv.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
/* system include files */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* application include files */
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include "lsb_addr_comp.h"
|
||||
|
||||
extern char *errmsg();
|
||||
extern int errno;
|
||||
extern int krb_debug;
|
||||
|
||||
/* static storage */
|
||||
|
||||
static u_long c_length;
|
||||
static int swap_bytes;
|
||||
static struct timeval local_time;
|
||||
static long delta_t;
|
||||
int private_msg_ver = KRB_PROT_VERSION;
|
||||
|
||||
/*
|
||||
#ifdef NOENCRPYTION
|
||||
* krb_rd_priv() checks the integrity of an
|
||||
#else
|
||||
* krb_rd_priv() decrypts and checks the integrity of an
|
||||
#endif
|
||||
* AUTH_MSG_PRIVATE message. Given the message received, "in",
|
||||
* the length of that message, "in_length", the key "schedule"
|
||||
* and "key", and the network addresses of the
|
||||
* "sender" and "receiver" of the message, krb_rd_safe() returns
|
||||
* RD_AP_OK if the message is okay, otherwise some error code.
|
||||
*
|
||||
* The message data retrieved from "in" are returned in the structure
|
||||
* "m_data". The pointer to the application data
|
||||
* (m_data->app_data) refers back to the appropriate place in "in".
|
||||
*
|
||||
* See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
|
||||
* message. The structure containing the extracted message
|
||||
* information, MSG_DAT, is defined in "krb.h".
|
||||
*/
|
||||
|
||||
long krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
|
||||
u_char *in; /* pointer to the msg received */
|
||||
u_long in_length; /* length of "in" msg */
|
||||
Key_schedule schedule; /* precomputed key schedule */
|
||||
C_Block key; /* encryption key for seed and ivec */
|
||||
struct sockaddr_in *sender;
|
||||
struct sockaddr_in *receiver;
|
||||
MSG_DAT *m_data; /*various input/output data from msg */
|
||||
{
|
||||
register u_char *p,*q;
|
||||
static u_long src_addr; /* Can't send structs since no
|
||||
* guarantees on size */
|
||||
|
||||
if (gettimeofday(&local_time,(struct timezone *)0))
|
||||
return -1;
|
||||
|
||||
p = in; /* beginning of message */
|
||||
swap_bytes = 0;
|
||||
|
||||
if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
|
||||
return RD_AP_VERSION;
|
||||
private_msg_ver = *(p-1);
|
||||
if (((*p) & ~1) != AUTH_MSG_PRIVATE)
|
||||
return RD_AP_MSG_TYPE;
|
||||
if ((*p++ & 1) != HOST_BYTE_ORDER)
|
||||
swap_bytes++;
|
||||
|
||||
/* get cipher length */
|
||||
bcopy((char *)p,(char *)&c_length,sizeof(c_length));
|
||||
if (swap_bytes)
|
||||
swap_u_long(c_length);
|
||||
p += sizeof(c_length);
|
||||
/* check for rational length so we don't go comatose */
|
||||
if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
|
||||
return RD_AP_MODIFIED;
|
||||
|
||||
|
||||
q = p; /* mark start of encrypted stuff */
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
pcbc_encrypt((C_Block *)q,(C_Block *)q,(long)c_length,schedule,key,DECRYPT);
|
||||
#endif
|
||||
|
||||
/* safely get application data length */
|
||||
bcopy((char *) p,(char *)&(m_data->app_length),
|
||||
sizeof(m_data->app_length));
|
||||
if (swap_bytes)
|
||||
swap_u_long(m_data->app_length);
|
||||
p += sizeof(m_data->app_length); /* skip over */
|
||||
|
||||
if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
|
||||
sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
|
||||
sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
|
||||
> in_length)
|
||||
return RD_AP_MODIFIED;
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
/* we're now at the decrypted application data */
|
||||
#endif
|
||||
m_data->app_data = p;
|
||||
|
||||
p += m_data->app_length;
|
||||
|
||||
/* safely get time_5ms */
|
||||
bcopy((char *) p, (char *)&(m_data->time_5ms),
|
||||
sizeof(m_data->time_5ms));
|
||||
/* don't need to swap-- one byte for now */
|
||||
p += sizeof(m_data->time_5ms);
|
||||
|
||||
/* safely get src address */
|
||||
bcopy((char *) p,(char *)&src_addr,sizeof(src_addr));
|
||||
/* don't swap, net order always */
|
||||
p += sizeof(src_addr);
|
||||
|
||||
if (src_addr != (u_long) sender->sin_addr.s_addr)
|
||||
return RD_AP_MODIFIED;
|
||||
|
||||
/* safely get time_sec */
|
||||
bcopy((char *) p, (char *)&(m_data->time_sec),
|
||||
sizeof(m_data->time_sec));
|
||||
if (swap_bytes) swap_u_long(m_data->time_sec);
|
||||
|
||||
p += sizeof(m_data->time_sec);
|
||||
|
||||
/* check direction bit is the sign bit */
|
||||
/* For compatibility with broken old code, compares are done in VAX
|
||||
byte order (LSBFIRST) */
|
||||
if (lsb_net_ulong_less(sender->sin_addr.s_addr,
|
||||
receiver->sin_addr.s_addr)==-1)
|
||||
/* src < recv */
|
||||
m_data->time_sec = - m_data->time_sec;
|
||||
else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
|
||||
receiver->sin_addr.s_addr)==0)
|
||||
if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
|
||||
/* src < recv */
|
||||
m_data->time_sec = - m_data->time_sec;
|
||||
/*
|
||||
* all that for one tiny bit!
|
||||
* Heaven help those that talk to themselves.
|
||||
*/
|
||||
|
||||
/* check the time integrity of the msg */
|
||||
delta_t = abs((int)((long) local_time.tv_sec
|
||||
- m_data->time_sec));
|
||||
if (delta_t > CLOCK_SKEW)
|
||||
return RD_AP_TIME;
|
||||
if (krb_debug)
|
||||
printf("\ndelta_t = %d",delta_t);
|
||||
|
||||
/*
|
||||
* caller must check timestamps for proper order and
|
||||
* replays, since server might have multiple clients
|
||||
* each with its own timestamps and we don't assume
|
||||
* tightly synchronized clocks.
|
||||
*/
|
||||
|
||||
#ifdef notdef
|
||||
bcopy((char *) p,(char *)&cksum,sizeof(cksum));
|
||||
if (swap_bytes) swap_u_long(cksum)
|
||||
/*
|
||||
* calculate the checksum of the length, sequence,
|
||||
* and input data, on the sending byte order!!
|
||||
*/
|
||||
calc_cksum = quad_cksum(q,NULL,p-q,0,key);
|
||||
|
||||
if (krb_debug)
|
||||
printf("\ncalc_cksum = %u, received cksum = %u",
|
||||
calc_cksum, cksum);
|
||||
if (cksum != calc_cksum)
|
||||
return RD_AP_MODIFIED;
|
||||
#endif
|
||||
return RD_AP_OK; /* OK == 0 */
|
||||
}
|
||||
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: der: rd_req.c,v 4.16 89/03/22 14:52:06 jtkohl Exp $
|
||||
* $Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: rd_req.c,v 1.2 1994/07/19 19:26:13 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include <sys/time.h>
|
||||
#include <strings.h>
|
||||
|
||||
extern int krb_ap_req_debug;
|
||||
|
||||
static struct timeval t_local = { 0, 0 };
|
||||
|
||||
/*
|
||||
* Keep the following information around for subsequent calls
|
||||
* to this routine by the same server using the same key.
|
||||
*/
|
||||
|
||||
static Key_schedule serv_key; /* Key sched to decrypt ticket */
|
||||
static C_Block ky; /* Initialization vector */
|
||||
static int st_kvno; /* version number for this key */
|
||||
static char st_rlm[REALM_SZ]; /* server's realm */
|
||||
static char st_nam[ANAME_SZ]; /* service name */
|
||||
static char st_inst[INST_SZ]; /* server's instance */
|
||||
|
||||
/*
|
||||
* This file contains two functions. krb_set_key() takes a DES
|
||||
* key or password string and returns a DES key (either the original
|
||||
* key, or the password converted into a DES key) and a key schedule
|
||||
* for it.
|
||||
*
|
||||
* krb_rd_req() reads an authentication request and returns information
|
||||
* about the identity of the requestor, or an indication that the
|
||||
* identity information was not authentic.
|
||||
*/
|
||||
|
||||
/*
|
||||
* krb_set_key() takes as its first argument either a DES key or a
|
||||
* password string. The "cvt" argument indicates how the first
|
||||
* argument "key" is to be interpreted: if "cvt" is null, "key" is
|
||||
* taken to be a DES key; if "cvt" is non-null, "key" is taken to
|
||||
* be a password string, and is converted into a DES key using
|
||||
* string_to_key(). In either case, the resulting key is returned
|
||||
* in the external static variable "ky". A key schedule is
|
||||
* generated for "ky" and returned in the external static variable
|
||||
* "serv_key".
|
||||
*
|
||||
* This routine returns the return value of des_key_sched.
|
||||
*
|
||||
* krb_set_key() needs to be in the same .o file as krb_rd_req() so that
|
||||
* the key set by krb_set_key() is available in private storage for
|
||||
* krb_rd_req().
|
||||
*/
|
||||
|
||||
int
|
||||
krb_set_key(key,cvt)
|
||||
char *key;
|
||||
int cvt;
|
||||
{
|
||||
#ifdef NOENCRYPTION
|
||||
bzero(ky, sizeof(ky));
|
||||
return KSUCCESS;
|
||||
#else
|
||||
if (cvt)
|
||||
string_to_key(key,ky);
|
||||
else
|
||||
bcopy(key,(char *)ky,8);
|
||||
return(des_key_sched(ky,serv_key));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
|
||||
* AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
|
||||
* checks its integrity and returns a judgement as to the requestor's
|
||||
* identity.
|
||||
*
|
||||
* The "authent" argument is a pointer to the received message.
|
||||
* The "service" and "instance" arguments name the receiving server,
|
||||
* and are used to get the service's ticket to decrypt the ticket
|
||||
* in the message, and to compare against the server name inside the
|
||||
* ticket. "from_addr" is the network address of the host from which
|
||||
* the message was received; this is checked against the network
|
||||
* address in the ticket. If "from_addr" is zero, the check is not
|
||||
* performed. "ad" is an AUTH_DAT structure which is
|
||||
* filled in with information about the sender's identity according
|
||||
* to the authenticator and ticket sent in the message. Finally,
|
||||
* "fn" contains the name of the file containing the server's key.
|
||||
* (If "fn" is NULL, the server's key is assumed to have been set
|
||||
* by krb_set_key(). If "fn" is the null string ("") the default
|
||||
* file KEYFILE, defined in "krb.h", is used.)
|
||||
*
|
||||
* krb_rd_req() returns RD_AP_OK if the authentication information
|
||||
* was genuine, or one of the following error codes (defined in
|
||||
* "krb.h"):
|
||||
*
|
||||
* RD_AP_VERSION - wrong protocol version number
|
||||
* RD_AP_MSG_TYPE - wrong message type
|
||||
* RD_AP_UNDEC - couldn't decipher the message
|
||||
* RD_AP_INCON - inconsistencies found
|
||||
* RD_AP_BADD - wrong network address
|
||||
* RD_AP_TIME - client time (in authenticator)
|
||||
* too far off server time
|
||||
* RD_AP_NYV - Kerberos time (in ticket) too
|
||||
* far off server time
|
||||
* RD_AP_EXP - ticket expired
|
||||
*
|
||||
* For the message format, see krb_mk_req().
|
||||
*
|
||||
* Mutual authentication is not implemented.
|
||||
*/
|
||||
|
||||
krb_rd_req(authent,service,instance,from_addr,ad,fn)
|
||||
register KTEXT authent; /* The received message */
|
||||
char *service; /* Service name */
|
||||
char *instance; /* Service instance */
|
||||
long from_addr; /* Net address of originating host */
|
||||
AUTH_DAT *ad; /* Structure to be filled in */
|
||||
char *fn; /* Filename to get keys from */
|
||||
{
|
||||
static KTEXT_ST ticket; /* Temp storage for ticket */
|
||||
static KTEXT tkt = &ticket;
|
||||
static KTEXT_ST req_id_st; /* Temp storage for authenticator */
|
||||
register KTEXT req_id = &req_id_st;
|
||||
|
||||
char realm[REALM_SZ]; /* Realm of issuing kerberos */
|
||||
static Key_schedule seskey_sched; /* Key sched for session key */
|
||||
unsigned char skey[KKEY_SZ]; /* Session key from ticket */
|
||||
char sname[SNAME_SZ]; /* Service name from ticket */
|
||||
char iname[INST_SZ]; /* Instance name from ticket */
|
||||
char r_aname[ANAME_SZ]; /* Client name from authenticator */
|
||||
char r_inst[INST_SZ]; /* Client instance from authenticator */
|
||||
char r_realm[REALM_SZ]; /* Client realm from authenticator */
|
||||
unsigned int r_time_ms; /* Fine time from authenticator */
|
||||
unsigned long r_time_sec; /* Coarse time from authenticator */
|
||||
register char *ptr; /* For stepping through */
|
||||
unsigned long delta_t; /* Time in authenticator - local time */
|
||||
long tkt_age; /* Age of ticket */
|
||||
static int swap_bytes; /* Need to swap bytes? */
|
||||
static int mutual; /* Mutual authentication requested? */
|
||||
static unsigned char s_kvno;/* Version number of the server's key
|
||||
* Kerberos used to encrypt ticket */
|
||||
int status;
|
||||
|
||||
if (authent->length <= 0)
|
||||
return(RD_AP_MODIFIED);
|
||||
|
||||
ptr = (char *) authent->dat;
|
||||
|
||||
/* get msg version, type and byte order, and server key version */
|
||||
|
||||
/* check version */
|
||||
if (KRB_PROT_VERSION != (unsigned int) *ptr++)
|
||||
return(RD_AP_VERSION);
|
||||
|
||||
/* byte order */
|
||||
swap_bytes = 0;
|
||||
if ((*ptr & 1) != HOST_BYTE_ORDER)
|
||||
swap_bytes++;
|
||||
|
||||
/* check msg type */
|
||||
mutual = 0;
|
||||
switch (*ptr++ & ~1) {
|
||||
case AUTH_MSG_APPL_REQUEST:
|
||||
break;
|
||||
case AUTH_MSG_APPL_REQUEST_MUTUAL:
|
||||
mutual++;
|
||||
break;
|
||||
default:
|
||||
return(RD_AP_MSG_TYPE);
|
||||
}
|
||||
|
||||
#ifdef lint
|
||||
/* XXX mutual is set but not used; why??? */
|
||||
/* this is a crock to get lint to shut up */
|
||||
if (mutual)
|
||||
mutual = 0;
|
||||
#endif /* lint */
|
||||
s_kvno = *ptr++; /* get server key version */
|
||||
(void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
|
||||
ptr += strlen(ptr) + 1; /* skip the realm "hint" */
|
||||
|
||||
/*
|
||||
* If "fn" is NULL, key info should already be set; don't
|
||||
* bother with ticket file. Otherwise, check to see if we
|
||||
* already have key info for the given server and key version
|
||||
* (saved in the static st_* variables). If not, go get it
|
||||
* from the ticket file. If "fn" is the null string, use the
|
||||
* default ticket file.
|
||||
*/
|
||||
if (fn && (strcmp(st_nam,service) || strcmp(st_inst,instance) ||
|
||||
strcmp(st_rlm,realm) || (st_kvno != s_kvno))) {
|
||||
if (*fn == 0) fn = KEYFILE;
|
||||
st_kvno = s_kvno;
|
||||
#ifndef NOENCRYPTION
|
||||
if (read_service_key(service,instance,realm,s_kvno,fn,(char *)skey))
|
||||
return(RD_AP_UNDEC);
|
||||
if (status=krb_set_key((char *)skey,0)) return(status);
|
||||
#endif
|
||||
(void) strcpy(st_rlm,realm);
|
||||
(void) strcpy(st_nam,service);
|
||||
(void) strcpy(st_inst,instance);
|
||||
}
|
||||
|
||||
/* Get ticket from authenticator */
|
||||
tkt->length = (int) *ptr++;
|
||||
if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
|
||||
return(RD_AP_MODIFIED);
|
||||
bcopy(ptr+1,(char *)(tkt->dat),tkt->length);
|
||||
|
||||
if (krb_ap_req_debug)
|
||||
log("ticket->length: %d",tkt->length);
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
/* Decrypt and take apart ticket */
|
||||
#endif
|
||||
|
||||
if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm,
|
||||
&(ad->address),ad->session, &(ad->life),
|
||||
&(ad->time_sec),sname,iname,ky,serv_key))
|
||||
return(RD_AP_UNDEC);
|
||||
|
||||
if (krb_ap_req_debug) {
|
||||
log("Ticket Contents.");
|
||||
log(" Aname: %s.%s",ad->pname,
|
||||
((int)*(ad->prealm) ? ad->prealm : "Athena"));
|
||||
log(" Service: %s%s%s",sname,((int)*iname ? "." : ""),iname);
|
||||
}
|
||||
|
||||
/* Extract the authenticator */
|
||||
req_id->length = (int) *(ptr++);
|
||||
if ((req_id->length + (ptr + tkt->length - (char *) authent->dat)) >
|
||||
authent->length)
|
||||
return(RD_AP_MODIFIED);
|
||||
bcopy(ptr + tkt->length, (char *)(req_id->dat),req_id->length);
|
||||
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(ad->session,seskey_sched);
|
||||
pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
|
||||
(long)req_id->length,seskey_sched,ad->session,DES_DECRYPT);
|
||||
#endif /* NOENCRYPTION */
|
||||
|
||||
#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
|
||||
|
||||
ptr = (char *) req_id->dat;
|
||||
(void) strcpy(r_aname,ptr); /* Authentication name */
|
||||
ptr += strlen(r_aname)+1;
|
||||
check_ptr();
|
||||
(void) strcpy(r_inst,ptr); /* Authentication instance */
|
||||
ptr += strlen(r_inst)+1;
|
||||
check_ptr();
|
||||
(void) strcpy(r_realm,ptr); /* Authentication name */
|
||||
ptr += strlen(r_realm)+1;
|
||||
check_ptr();
|
||||
bcopy(ptr,(char *)&ad->checksum,4); /* Checksum */
|
||||
ptr += 4;
|
||||
check_ptr();
|
||||
if (swap_bytes) swap_u_long(ad->checksum);
|
||||
r_time_ms = *(ptr++); /* Time (fine) */
|
||||
#ifdef lint
|
||||
/* XXX r_time_ms is set but not used. why??? */
|
||||
/* this is a crock to get lint to shut up */
|
||||
if (r_time_ms)
|
||||
r_time_ms = 0;
|
||||
#endif /* lint */
|
||||
check_ptr();
|
||||
/* assume sizeof(r_time_sec) == 4 ?? */
|
||||
bcopy(ptr,(char *)&r_time_sec,4); /* Time (coarse) */
|
||||
if (swap_bytes) swap_u_long(r_time_sec);
|
||||
|
||||
/* Check for authenticity of the request */
|
||||
if (krb_ap_req_debug)
|
||||
log("Pname: %s %s",ad->pname,r_aname);
|
||||
if (strcmp(ad->pname,r_aname) != 0)
|
||||
return(RD_AP_INCON);
|
||||
if (strcmp(ad->pinst,r_inst) != 0)
|
||||
return(RD_AP_INCON);
|
||||
if (krb_ap_req_debug)
|
||||
log("Realm: %s %s",ad->prealm,r_realm);
|
||||
if ((strcmp(ad->prealm,r_realm) != 0))
|
||||
return(RD_AP_INCON);
|
||||
|
||||
if (krb_ap_req_debug)
|
||||
log("Address: %d %d",ad->address,from_addr);
|
||||
if (from_addr && (ad->address != from_addr))
|
||||
return(RD_AP_BADD);
|
||||
|
||||
(void) gettimeofday(&t_local,(struct timezone *) 0);
|
||||
delta_t = abs((int)(t_local.tv_sec - r_time_sec));
|
||||
if (delta_t > CLOCK_SKEW) {
|
||||
if (krb_ap_req_debug)
|
||||
log("Time out of range: %d - %d = %d",
|
||||
t_local.tv_sec,r_time_sec,delta_t);
|
||||
return(RD_AP_TIME);
|
||||
}
|
||||
|
||||
/* Now check for expiration of ticket */
|
||||
|
||||
tkt_age = t_local.tv_sec - ad->time_sec;
|
||||
if (krb_ap_req_debug)
|
||||
log("Time: %d Issue Date: %d Diff: %d Life %x",
|
||||
t_local.tv_sec,ad->time_sec,tkt_age,ad->life);
|
||||
|
||||
if (t_local.tv_sec < ad->time_sec) {
|
||||
if ((ad->time_sec - t_local.tv_sec) > CLOCK_SKEW)
|
||||
return(RD_AP_NYV);
|
||||
}
|
||||
else if ((t_local.tv_sec - ad->time_sec) > 5 * 60 * ad->life)
|
||||
return(RD_AP_EXP);
|
||||
|
||||
/* All seems OK */
|
||||
ad->reply.length = 0;
|
||||
|
||||
return(RD_AP_OK);
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* This routine dissects a a Kerberos 'safe msg', checking its
|
||||
* integrity, and returning a pointer to the application data
|
||||
* contained and its length.
|
||||
*
|
||||
* Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
|
||||
*
|
||||
* Steve Miller Project Athena MIT/DEC
|
||||
*
|
||||
* from: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $
|
||||
* $Id: rd_safe.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: rd_safe.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
/* system include files */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* application include files */
|
||||
#include <des.h>
|
||||
#include <krb.h>
|
||||
#include <prot.h>
|
||||
#include "lsb_addr_comp.h"
|
||||
|
||||
extern char *errmsg();
|
||||
extern int errno;
|
||||
extern int krb_debug;
|
||||
|
||||
/* static storage */
|
||||
|
||||
static C_Block calc_cksum[2];
|
||||
static C_Block big_cksum[2];
|
||||
static int swap_bytes;
|
||||
static struct timeval local_time;
|
||||
static u_long delta_t;
|
||||
|
||||
/*
|
||||
* krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
|
||||
* Given the message received, "in", the length of that message,
|
||||
* "in_length", the "key" to compute the checksum with, and the
|
||||
* network addresses of the "sender" and "receiver" of the message,
|
||||
* krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
|
||||
* some error code.
|
||||
*
|
||||
* The message data retrieved from "in" is returned in the structure
|
||||
* "m_data". The pointer to the application data (m_data->app_data)
|
||||
* refers back to the appropriate place in "in".
|
||||
*
|
||||
* See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
|
||||
* message. The structure containing the extracted message
|
||||
* information, MSG_DAT, is defined in "krb.h".
|
||||
*/
|
||||
|
||||
long krb_rd_safe(in,in_length,key,sender,receiver,m_data)
|
||||
u_char *in; /* pointer to the msg received */
|
||||
u_long in_length; /* length of "in" msg */
|
||||
C_Block *key; /* encryption key for seed and ivec */
|
||||
struct sockaddr_in *sender; /* sender's address */
|
||||
struct sockaddr_in *receiver; /* receiver's address -- me */
|
||||
MSG_DAT *m_data; /* where to put message information */
|
||||
{
|
||||
register u_char *p,*q;
|
||||
static u_long src_addr; /* Can't send structs since no
|
||||
* guarantees on size */
|
||||
/* Be very conservative */
|
||||
if (sizeof(u_long) != sizeof(struct in_addr)) {
|
||||
fprintf(stderr,"\n\
|
||||
krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (gettimeofday(&local_time,(struct timezone *)0))
|
||||
return -1;
|
||||
|
||||
p = in; /* beginning of message */
|
||||
swap_bytes = 0;
|
||||
|
||||
if (*p++ != KRB_PROT_VERSION) return RD_AP_VERSION;
|
||||
if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
|
||||
if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
|
||||
|
||||
q = p; /* mark start of cksum stuff */
|
||||
|
||||
/* safely get length */
|
||||
bcopy((char *)p,(char *)&(m_data->app_length),
|
||||
sizeof(m_data->app_length));
|
||||
if (swap_bytes) swap_u_long(m_data->app_length);
|
||||
p += sizeof(m_data->app_length); /* skip over */
|
||||
|
||||
if (m_data->app_length + sizeof(in_length)
|
||||
+ sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
|
||||
+ sizeof(big_cksum) + sizeof(src_addr)
|
||||
+ VERSION_SZ + MSG_TYPE_SZ > in_length)
|
||||
return(RD_AP_MODIFIED);
|
||||
|
||||
m_data->app_data = p; /* we're now at the application data */
|
||||
|
||||
/* skip app data */
|
||||
p += m_data->app_length;
|
||||
|
||||
/* safely get time_5ms */
|
||||
bcopy((char *)p, (char *)&(m_data->time_5ms),
|
||||
sizeof(m_data->time_5ms));
|
||||
|
||||
/* don't need to swap-- one byte for now */
|
||||
p += sizeof(m_data->time_5ms);
|
||||
|
||||
/* safely get src address */
|
||||
bcopy((char *)p,(char *)&src_addr,sizeof(src_addr));
|
||||
|
||||
/* don't swap, net order always */
|
||||
p += sizeof(src_addr);
|
||||
|
||||
if (src_addr != (u_long) sender->sin_addr.s_addr)
|
||||
return RD_AP_MODIFIED;
|
||||
|
||||
/* safely get time_sec */
|
||||
bcopy((char *)p, (char *)&(m_data->time_sec),
|
||||
sizeof(m_data->time_sec));
|
||||
if (swap_bytes)
|
||||
swap_u_long(m_data->time_sec);
|
||||
p += sizeof(m_data->time_sec);
|
||||
|
||||
/* check direction bit is the sign bit */
|
||||
/* For compatibility with broken old code, compares are done in VAX
|
||||
byte order (LSBFIRST) */
|
||||
if (lsb_net_ulong_less(sender->sin_addr.s_addr,
|
||||
receiver->sin_addr.s_addr)==-1)
|
||||
/* src < recv */
|
||||
m_data->time_sec = - m_data->time_sec;
|
||||
else if (lsb_net_ulong_less(sender->sin_addr.s_addr,
|
||||
receiver->sin_addr.s_addr)==0)
|
||||
if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
|
||||
/* src < recv */
|
||||
m_data->time_sec = - m_data->time_sec;
|
||||
|
||||
/*
|
||||
* All that for one tiny bit! Heaven help those that talk to
|
||||
* themselves.
|
||||
*/
|
||||
|
||||
/* check the time integrity of the msg */
|
||||
delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec));
|
||||
if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
|
||||
|
||||
/*
|
||||
* caller must check timestamps for proper order and replays, since
|
||||
* server might have multiple clients each with its own timestamps
|
||||
* and we don't assume tightly synchronized clocks.
|
||||
*/
|
||||
|
||||
bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum));
|
||||
if (swap_bytes) swap_u_16(big_cksum);
|
||||
|
||||
#ifdef NOENCRYPTION
|
||||
bzero(calc_cksum, sizeof(calc_cksum));
|
||||
#else
|
||||
quad_cksum(q,calc_cksum,p-q,2,key);
|
||||
#endif
|
||||
|
||||
if (krb_debug)
|
||||
printf("\ncalc_cksum = %u, received cksum = %u",
|
||||
(long) calc_cksum[0], (long) big_cksum[0]);
|
||||
if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
|
||||
return(RD_AP_MODIFIED);
|
||||
|
||||
return(RD_AP_OK); /* OK == 0 */
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: _service_key.c,v 4.10 90/03/10 19:06:56 jon Exp $
|
||||
* $Id: read_service_key.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: read_service_key.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <krb.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*
|
||||
* The private keys for servers on a given host are stored in a
|
||||
* "srvtab" file (typically "/etc/srvtab"). This routine extracts
|
||||
* a given server's key from the file.
|
||||
*
|
||||
* read_service_key() takes the server's name ("service"), "instance",
|
||||
* and "realm" and a key version number "kvno", and looks in the given
|
||||
* "file" for the corresponding entry, and if found, returns the entry's
|
||||
* key field in "key".
|
||||
*
|
||||
* If "instance" contains the string "*", then it will match
|
||||
* any instance, and the chosen instance will be copied to that
|
||||
* string. For this reason it is important that the there is enough
|
||||
* space beyond the "*" to receive the entry.
|
||||
*
|
||||
* If "kvno" is 0, it is treated as a wild card and the first
|
||||
* matching entry regardless of the "vno" field is returned.
|
||||
*
|
||||
* This routine returns KSUCCESS on success, otherwise KFAILURE.
|
||||
*
|
||||
* The format of each "srvtab" entry is as follows:
|
||||
*
|
||||
* Size Variable Field in file
|
||||
* ---- -------- -------------
|
||||
* string serv server name
|
||||
* string inst server instance
|
||||
* string realm server realm
|
||||
* 1 byte vno server key version #
|
||||
* 8 bytes key server's key
|
||||
* ... ... ...
|
||||
*/
|
||||
|
||||
|
||||
/*ARGSUSED */
|
||||
read_service_key(service,instance,realm,kvno,file,key)
|
||||
char *service; /* Service Name */
|
||||
char *instance; /* Instance name or "*" */
|
||||
char *realm; /* Realm */
|
||||
int kvno; /* Key version number */
|
||||
char *file; /* Filename */
|
||||
char *key; /* Pointer to key to be filled in */
|
||||
{
|
||||
char serv[SNAME_SZ];
|
||||
char inst[INST_SZ];
|
||||
char rlm[REALM_SZ];
|
||||
unsigned char vno; /* Key version number */
|
||||
int wcard;
|
||||
|
||||
int stab, open();
|
||||
|
||||
if ((stab = open(file, 0, 0)) < NULL)
|
||||
return(KFAILURE);
|
||||
|
||||
wcard = (instance[0] == '*') && (instance[1] == '\0');
|
||||
|
||||
while(getst(stab,serv,SNAME_SZ) > 0) { /* Read sname */
|
||||
(void) getst(stab,inst,INST_SZ); /* Instance */
|
||||
(void) getst(stab,rlm,REALM_SZ); /* Realm */
|
||||
/* Vers number */
|
||||
if (read(stab,(char *)&vno,1) != 1) {
|
||||
close(stab);
|
||||
return(KFAILURE);
|
||||
}
|
||||
/* Key */
|
||||
if (read(stab,key,8) != 8) {
|
||||
close(stab);
|
||||
return(KFAILURE);
|
||||
}
|
||||
/* Is this the right service */
|
||||
if (strcmp(serv,service))
|
||||
continue;
|
||||
/* How about instance */
|
||||
if (!wcard && strcmp(inst,instance))
|
||||
continue;
|
||||
if (wcard)
|
||||
(void) strncpy(instance,inst,INST_SZ);
|
||||
/* Is this the right realm */
|
||||
#ifdef ATHENA_COMPAT
|
||||
/* XXX For backward compatibility: if keyfile says "Athena"
|
||||
and caller wants "ATHENA.MIT.EDU", call it a match */
|
||||
if (strcmp(rlm,realm) &&
|
||||
(strcmp(rlm,"Athena") ||
|
||||
strcmp(realm,"ATHENA.MIT.EDU")))
|
||||
continue;
|
||||
#else /* ! ATHENA_COMPAT */
|
||||
if (strcmp(rlm,realm))
|
||||
continue;
|
||||
#endif /* ATHENA_COMPAT */
|
||||
|
||||
/* How about the key version number */
|
||||
if (kvno && kvno != (int) vno)
|
||||
continue;
|
||||
|
||||
(void) close(stab);
|
||||
return(KSUCCESS);
|
||||
}
|
||||
|
||||
/* Can't find the requested service */
|
||||
(void) close(stab);
|
||||
return(KFAILURE);
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: recvauth.c,v 4.4 90/03/10 19:03:08 jon Exp $";
|
||||
* $Id: recvauth.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: recvauth.c,v 1.1.1.1 1994/09/30 14:50:03 csgr Exp $";
|
||||
#endif lint
|
||||
|
||||
#include <krb.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
|
||||
#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
|
||||
chars */
|
||||
|
||||
/*
|
||||
* If the protocol changes, you will need to change the version string
|
||||
* and make appropriate changes in krb_sendauth.c
|
||||
* be sure to support old versions of krb_sendauth!
|
||||
*/
|
||||
|
||||
extern int errno;
|
||||
|
||||
/*
|
||||
* krb_recvauth() reads (and optionally responds to) a message sent
|
||||
* using krb_sendauth(). The "options" argument is a bit-field of
|
||||
* selected options (see "sendauth.c" for options description).
|
||||
* The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL
|
||||
* (mutual authentication requested). The "fd" argument supplies
|
||||
* a file descriptor to read from (and write to, if mutual authenti-
|
||||
* cation is requested).
|
||||
*
|
||||
* Part of the received message will be a Kerberos ticket sent by the
|
||||
* client; this is read into the "ticket" argument. The "service" and
|
||||
* "instance" arguments supply the server's Kerberos name. If the
|
||||
* "instance" argument is the string "*", it is treated as a wild card
|
||||
* and filled in during the krb_rd_req() call (see read_service_key()).
|
||||
*
|
||||
* The "faddr" and "laddr" give the sending (client) and receiving
|
||||
* (local server) network addresses. ("laddr" may be left NULL unless
|
||||
* mutual authentication is requested, in which case it must be set.)
|
||||
*
|
||||
* The authentication information extracted from the message is returned
|
||||
* in "kdata". The "filename" argument indicates the file where the
|
||||
* server's key can be found. (It is passed on to krb_rd_req().) If
|
||||
* left null, the default "/etc/srvtab" will be used.
|
||||
*
|
||||
* If mutual authentication is requested, the session key schedule must
|
||||
* be computed in order to reply; this schedule is returned in the
|
||||
* "schedule" argument. A string containing the application version
|
||||
* number from the received message is returned in "version", which
|
||||
* should be large enough to hold a KRB_SENDAUTH_VLEN-character string.
|
||||
*
|
||||
* See krb_sendauth() for the format of the received client message.
|
||||
*
|
||||
* This routine supports another client format, for backward
|
||||
* compatibility, consisting of:
|
||||
*
|
||||
* Size Variable Field
|
||||
* ---- -------- -----
|
||||
*
|
||||
* string tmp_buf, tkt_len length of ticket, in
|
||||
* ascii
|
||||
*
|
||||
* char ' ' (space char) separator
|
||||
*
|
||||
* tkt_len ticket->dat the ticket
|
||||
*
|
||||
* This old-style version does not support mutual authentication.
|
||||
*
|
||||
* krb_recvauth() first reads the protocol version string from the
|
||||
* given file descriptor. If it doesn't match the current protocol
|
||||
* version (KRB_SENDAUTH_VERS), the old-style format is assumed. In
|
||||
* that case, the string of characters up to the first space is read
|
||||
* and interpreted as the ticket length, then the ticket is read.
|
||||
*
|
||||
* If the first string did match KRB_SENDAUTH_VERS, krb_recvauth()
|
||||
* next reads the application protocol version string. Then the
|
||||
* ticket length and ticket itself are read.
|
||||
*
|
||||
* The ticket is decrypted and checked by the call to krb_rd_req().
|
||||
* If no mutual authentication is required, the result of the
|
||||
* krb_rd_req() call is retured by this routine. If mutual authenti-
|
||||
* cation is required, a message in the following format is returned
|
||||
* on "fd":
|
||||
*
|
||||
* Size Variable Field
|
||||
* ---- -------- -----
|
||||
*
|
||||
* 4 bytes tkt_len length of ticket or -1
|
||||
* if error occurred
|
||||
*
|
||||
* priv_len tmp_buf "private" message created
|
||||
* by krb_mk_priv() which
|
||||
* contains the incremented
|
||||
* checksum sent by the client
|
||||
* encrypted in the session
|
||||
* key. (This field is not
|
||||
* present in case of error.)
|
||||
*
|
||||
* If all goes well, KSUCCESS is returned; otherwise KFAILURE or some
|
||||
* other error code is returned.
|
||||
*/
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif /* max */
|
||||
|
||||
int
|
||||
krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
|
||||
filename, schedule, version)
|
||||
long options; /* bit-pattern of options */
|
||||
int fd; /* file descr. to read from */
|
||||
KTEXT ticket; /* storage for client's ticket */
|
||||
char *service; /* service expected */
|
||||
char *instance; /* inst expected (may be filled in) */
|
||||
struct sockaddr_in *faddr; /* address of foreign host on fd */
|
||||
struct sockaddr_in *laddr; /* local address */
|
||||
AUTH_DAT *kdata; /* kerberos data (returned) */
|
||||
char *filename; /* name of file with service keys */
|
||||
Key_schedule schedule; /* key schedule (return) */
|
||||
char *version; /* version string (filled in) */
|
||||
{
|
||||
|
||||
int i, cc, old_vers = 0;
|
||||
char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */
|
||||
char *cp;
|
||||
int rem;
|
||||
long tkt_len, priv_len;
|
||||
u_long cksum;
|
||||
u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)];
|
||||
|
||||
/* read the protocol version number */
|
||||
if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) !=
|
||||
KRB_SENDAUTH_VLEN)
|
||||
return(errno);
|
||||
krb_vers[KRB_SENDAUTH_VLEN] = '\0';
|
||||
|
||||
/* check version string */
|
||||
if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) {
|
||||
/* Assume the old version of sendkerberosdata: send ascii
|
||||
length, ' ', and ticket. */
|
||||
if (options & KOPT_DO_MUTUAL)
|
||||
return(KFAILURE); /* XXX can't do old style with mutual auth */
|
||||
old_vers = 1;
|
||||
|
||||
/* copy what we have read into tmp_buf */
|
||||
(void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN);
|
||||
|
||||
/* search for space, and make it a null */
|
||||
for (i = 0; i < KRB_SENDAUTH_VLEN; i++)
|
||||
if (tmp_buf[i]== ' ') {
|
||||
tmp_buf[i] = '\0';
|
||||
/* point cp to the beginning of the real ticket */
|
||||
cp = (char *) &tmp_buf[i+1];
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == KRB_SENDAUTH_VLEN)
|
||||
/* didn't find the space, keep reading to find it */
|
||||
for (; i<20; i++) {
|
||||
if (read(fd, (char *)&tmp_buf[i], 1) != 1) {
|
||||
return(KFAILURE);
|
||||
}
|
||||
if (tmp_buf[i] == ' ') {
|
||||
tmp_buf[i] = '\0';
|
||||
/* point cp to the beginning of the real ticket */
|
||||
cp = (char *) &tmp_buf[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tkt_len = (long) atoi((char *) tmp_buf);
|
||||
|
||||
/* sanity check the length */
|
||||
if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN))
|
||||
return(KFAILURE);
|
||||
|
||||
if (i < KRB_SENDAUTH_VLEN) {
|
||||
/* since we already got the space, and part of the ticket,
|
||||
we read fewer bytes to get the rest of the ticket */
|
||||
if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
|
||||
(int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
|
||||
!= (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
|
||||
return(errno);
|
||||
} else {
|
||||
if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
|
||||
(int) tkt_len)
|
||||
return(errno);
|
||||
}
|
||||
ticket->length = tkt_len;
|
||||
/* copy the ticket into the struct */
|
||||
(void) bcopy(cp, (char *) ticket->dat, ticket->length);
|
||||
|
||||
} else {
|
||||
/* read the application version string */
|
||||
if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
|
||||
KRB_SENDAUTH_VLEN)
|
||||
return(errno);
|
||||
version[KRB_SENDAUTH_VLEN] = '\0';
|
||||
|
||||
/* get the length of the ticket */
|
||||
if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
|
||||
sizeof(tkt_len))
|
||||
return(errno);
|
||||
|
||||
/* sanity check */
|
||||
ticket->length = ntohl((unsigned long)tkt_len);
|
||||
if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
|
||||
if (options & KOPT_DO_MUTUAL) {
|
||||
rem = KFAILURE;
|
||||
goto mutual_fail;
|
||||
} else
|
||||
return(KFAILURE); /* XXX there may still be junk on the fd? */
|
||||
}
|
||||
|
||||
/* read the ticket */
|
||||
if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
|
||||
!= ticket->length)
|
||||
return(errno);
|
||||
}
|
||||
/*
|
||||
* now have the ticket. decrypt it to get the authenticated
|
||||
* data.
|
||||
*/
|
||||
rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
|
||||
kdata,filename);
|
||||
|
||||
if (old_vers) return(rem); /* XXX can't do mutual with old client */
|
||||
|
||||
/* if we are doing mutual auth, compose a response */
|
||||
if (options & KOPT_DO_MUTUAL) {
|
||||
if (rem != KSUCCESS)
|
||||
/* the krb_rd_req failed */
|
||||
goto mutual_fail;
|
||||
|
||||
/* add one to the (formerly) sealed checksum, and re-seal it
|
||||
for return to the client */
|
||||
cksum = kdata->checksum + 1;
|
||||
cksum = htonl(cksum);
|
||||
#ifndef NOENCRYPTION
|
||||
key_sched(kdata->session,schedule);
|
||||
#endif
|
||||
priv_len = krb_mk_priv((unsigned char *)&cksum,
|
||||
tmp_buf,
|
||||
(unsigned long) sizeof(cksum),
|
||||
schedule,
|
||||
kdata->session,
|
||||
laddr,
|
||||
faddr);
|
||||
if (priv_len < 0) {
|
||||
/* re-sealing failed; notify the client */
|
||||
rem = KFAILURE; /* XXX */
|
||||
mutual_fail:
|
||||
priv_len = -1;
|
||||
tkt_len = htonl((unsigned long) priv_len);
|
||||
/* a length of -1 is interpreted as an authentication
|
||||
failure by the client */
|
||||
if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
|
||||
!= sizeof(tkt_len))
|
||||
return(cc);
|
||||
return(rem);
|
||||
} else {
|
||||
/* re-sealing succeeded, send the private message */
|
||||
tkt_len = htonl((unsigned long)priv_len);
|
||||
if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
|
||||
!= sizeof(tkt_len))
|
||||
return(cc);
|
||||
if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
|
||||
!= (int) priv_len)
|
||||
return(cc);
|
||||
}
|
||||
}
|
||||
return(rem);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* For copying and distribution information, please see the file
|
||||
* <Copyright.MIT>.
|
||||
*
|
||||
* from: save_credentials.c,v 4.9 89/05/31 17:45:43 jtkohl Exp $
|
||||
* $Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char *rcsid =
|
||||
"$Id: save_credentials.c,v 1.2 1994/07/19 19:26:19 g89r4222 Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <krb.h>
|
||||
|
||||
/*
|
||||
* This routine takes a ticket and associated info and calls
|
||||
* tf_save_cred() to store them in the ticket cache. The peer
|
||||
* routine for extracting a ticket and associated info from the
|
||||
* ticket cache is krb_get_cred(). When changes are made to
|
||||
* this routine, the corresponding changes should be made
|
||||
* in krb_get_cred() as well.
|
||||
*
|
||||
* Returns KSUCCESS if all goes well, otherwise an error returned
|
||||
* by the tf_init() or tf_save_cred() routines.
|
||||
*/
|
||||
|
||||
save_credentials(service, instance, realm, session, lifetime, kvno,
|
||||
ticket, issue_date)
|
||||
char *service; /* Service name */
|
||||
char *instance; /* Instance */
|
||||
char *realm; /* Auth domain */
|
||||
C_Block session; /* Session key */
|
||||
int lifetime; /* Lifetime */
|
||||
int kvno; /* Key version number */
|
||||
KTEXT ticket; /* The ticket itself */
|
||||
long issue_date; /* The issue time */
|
||||
{
|
||||
int tf_status; /* return values of the tf_util calls */
|
||||
|
||||
/* Open and lock the ticket file for writing */
|
||||
if ((tf_status = tf_init(TKT_FILE, W_TKT_FIL)) != KSUCCESS)
|
||||
return(tf_status);
|
||||
|
||||
/* Save credentials by appending to the ticket file */
|
||||
tf_status = tf_save_cred(service, instance, realm, session,
|
||||
lifetime, kvno, ticket, issue_date);
|
||||
(void) tf_close();
|
||||
return (tf_status);
|
||||
}
|
||||
Loaded 100 of 2494 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user