aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb4/put_svc_key.c
blob: e2eb24d84d1feca9828dbc7cb081201069c7e35f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* lib/krb/put_svc_key.c */
/* Copyright 1994 Cygnus Support */
/* Mark W. Eichin */
/*
 * 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.
 * Cygnus Support makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is" without express
 * or implied warranty.
 */

/*
 * put_svc_key is a simple version of what 'ksrvutil add' provides, for some
 *    circumstances when service keys are distributed by applictions.
 *
 * Caveats: currently uses UNIX I/O (open, read) rather than stdio - this 
 *    should be fixed.
 *          It could probably be made more general (and then actually be used
 *    by ksrvutil.) This version supports just enough to be useful.
 */

#include "krb.h"
#include "krb4int.h"

#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

extern char *krb__get_srvtabname();

#define KEYSZ sizeof(C_Block)
/* strict put_svc_key.
   The srvtab must already exist;
   The key (exact match) must already be in the file;
   version numbers are not checked.
 */
KRB5_DLLIMP int KRB5_CALLCONV
put_svc_key(sfile,name,inst,realm,newvno,key)
	char FAR *sfile;
	char FAR *name;
	char FAR *inst;
	char FAR *realm;
	int newvno;
	char FAR *key;
{
	int fd;
	char fname[SNAME_SZ], finst[INST_SZ], frlm[REALM_SZ];
	unsigned char fvno;
	char fkey[KEYSZ];

	if (!sfile)
		sfile = KEYFILE;

	if ((fd = open(sfile, O_RDWR)) < 0)
		return KFAILURE;

	while(getst(fd,fname,SNAME_SZ) > 0) {
		getst(fd,finst,INST_SZ);
		getst(fd,frlm,REALM_SZ);
		if (!strcmp(fname,name)
		    && !strcmp(finst,inst)
		    && !strcmp(frlm,realm)) {
			/* all matched, so write new data */
			fvno = newvno;
			lseek(fd,0,SEEK_CUR);
			if (write(fd,&fvno,1) != 1) {
				close(fd);
				return KFAILURE;
			}
			if (write(fd,key,KEYSZ) != KEYSZ) {
				close(fd);
				return KFAILURE;
			}
			close(fd);
			return KSUCCESS;
		}
                if (read(fd,&fvno,1) != 1) {
                        close(fd);
                        return KFAILURE;
                }
                if (read(fd,fkey,KEYSZ) != KEYSZ) {
                        close(fd);
                        return KFAILURE;
                }
	}
	/* never found it */
	close(fd);
	return KFAILURE;
}