1 | /* |
---|
2 | * kadm_ser_wrap.c |
---|
3 | * |
---|
4 | * Copyright 1988 by the Massachusetts Institute of Technology. |
---|
5 | * |
---|
6 | * For copying and distribution information, please see the file |
---|
7 | * <mit-copyright.h>. |
---|
8 | * |
---|
9 | * Kerberos administration server-side support functions |
---|
10 | * unwraps wrapped packets and calls the appropriate server subroutine |
---|
11 | */ |
---|
12 | |
---|
13 | #include <mit-copyright.h> |
---|
14 | #include <stdio.h> |
---|
15 | #include <string.h> |
---|
16 | #include <sys/types.h> |
---|
17 | #define DEFINE_SOCKADDR |
---|
18 | #include <krb.h> /* For krb_db.h */ |
---|
19 | #include <krb_db.h> /* For kdb_get_master_key, etc */ |
---|
20 | #include <kadm.h> |
---|
21 | #include <kadm_err.h> |
---|
22 | #include <krb_err.h> |
---|
23 | #include <krbports.h> |
---|
24 | #include "kadm_server.h" |
---|
25 | |
---|
26 | Kadm_Server server_parm; |
---|
27 | |
---|
28 | /* |
---|
29 | kadm_ser_init |
---|
30 | set up the server_parm structure |
---|
31 | */ |
---|
32 | int |
---|
33 | kadm_ser_init(inter, realm, kfile) |
---|
34 | int inter; /* interactive or from file */ |
---|
35 | char realm[]; |
---|
36 | char *kfile; |
---|
37 | { |
---|
38 | struct servent *sep; |
---|
39 | u_short sep_port; |
---|
40 | struct hostent *hp; |
---|
41 | char hostname[MAXHOSTNAMELEN]; |
---|
42 | |
---|
43 | (void) init_kadm_err_tbl(); |
---|
44 | (void) init_krb_err_tbl(); |
---|
45 | if (gethostname(hostname, sizeof(hostname))) |
---|
46 | return KADM_NO_HOSTNAME; |
---|
47 | |
---|
48 | (void) strcpy(server_parm.sname, PWSERV_NAME); |
---|
49 | (void) strcpy(server_parm.sinst, KRB_MASTER); |
---|
50 | (void) strcpy(server_parm.krbrlm, realm); |
---|
51 | |
---|
52 | server_parm.admin_fd = -1; |
---|
53 | /* setting up the addrs */ |
---|
54 | if (sep = getservbyname(KADM_SNAME, "tcp")) |
---|
55 | sep_port = sep->s_port; |
---|
56 | else |
---|
57 | sep_port = htons(KADM_PORT); /* KADM_SNAME == kerberos_master/tcp */ |
---|
58 | memset((char *)&server_parm.admin_addr, 0,sizeof(server_parm.admin_addr)); |
---|
59 | server_parm.admin_addr.sin_family = AF_INET; |
---|
60 | if ((hp = gethostbyname(hostname)) == NULL) |
---|
61 | return KADM_NO_HOSTNAME; |
---|
62 | memcpy((char *) &server_parm.admin_addr.sin_addr.s_addr, hp->h_addr, |
---|
63 | hp->h_length); |
---|
64 | server_parm.admin_addr.sin_port = sep_port; |
---|
65 | /* setting up the database */ |
---|
66 | if (kdb_get_master_key_from((inter==1),server_parm.master_key, |
---|
67 | server_parm.master_key_schedule, 0, kfile) != 0) |
---|
68 | return KADM_NO_MAST; |
---|
69 | if ((server_parm.master_key_version = |
---|
70 | kdb_verify_master_key(server_parm.master_key, |
---|
71 | server_parm.master_key_schedule,stderr))<0) |
---|
72 | return KADM_NO_VERI; |
---|
73 | return KADM_SUCCESS; |
---|
74 | } |
---|
75 | |
---|
76 | static void |
---|
77 | errpkt(dat, dat_len, code) |
---|
78 | u_char **dat; |
---|
79 | int *dat_len; |
---|
80 | int code; |
---|
81 | { |
---|
82 | unsigned KRB_INT32 retcode; |
---|
83 | char *pdat; |
---|
84 | extern char *malloc(); |
---|
85 | |
---|
86 | free((char *)*dat); /* free up req */ |
---|
87 | *dat_len = KADM_VERSIZE + sizeof(retcode); |
---|
88 | *dat = (u_char *) malloc((unsigned)*dat_len); |
---|
89 | pdat = (char *) *dat; |
---|
90 | retcode = htonl((u_long) code); |
---|
91 | (void) strncpy(pdat, KADM_ULOSE, KADM_VERSIZE); |
---|
92 | memcpy(&pdat[KADM_VERSIZE], (char *)&retcode, sizeof(retcode)); |
---|
93 | return; |
---|
94 | } |
---|
95 | |
---|
96 | /* |
---|
97 | kadm_ser_in |
---|
98 | unwrap the data stored in dat, process, and return it. |
---|
99 | */ |
---|
100 | int |
---|
101 | kadm_ser_in(dat,dat_len) |
---|
102 | u_char **dat; |
---|
103 | int *dat_len; |
---|
104 | { |
---|
105 | u_char *in_st; /* pointer into the sent packet */ |
---|
106 | int in_len,retc; /* where in packet we are, for |
---|
107 | returns */ |
---|
108 | unsigned KRB_INT32 r_len; /* length of the actual packet */ |
---|
109 | KTEXT_ST authent; /* the authenticator */ |
---|
110 | AUTH_DAT ad; /* who is this, klink */ |
---|
111 | u_long ncksum; /* checksum of encrypted data */ |
---|
112 | des_key_schedule sess_sched; /* our schedule */ |
---|
113 | MSG_DAT msg_st; |
---|
114 | u_char *retdat, *tmpdat; |
---|
115 | KRB_INT32 retval; |
---|
116 | int retlen; |
---|
117 | extern char *malloc(); |
---|
118 | |
---|
119 | if (strncmp(KADM_VERSTR, (char *)*dat, KADM_VERSIZE)) { |
---|
120 | errpkt(dat, dat_len, KADM_BAD_VER); |
---|
121 | return KADM_BAD_VER; |
---|
122 | } |
---|
123 | in_len = KADM_VERSIZE; |
---|
124 | /* get the length */ |
---|
125 | if ((retc = stv_long(*dat, &r_len, in_len, *dat_len)) < 0) |
---|
126 | return KADM_LENGTH_ERROR; |
---|
127 | in_len += retc; |
---|
128 | authent.length = *dat_len - r_len - KADM_VERSIZE - sizeof(KRB_INT32); |
---|
129 | memcpy((char *)authent.dat, (char *)(*dat) + in_len, authent.length); |
---|
130 | authent.mbz = 0; |
---|
131 | /* service key should be set before here */ |
---|
132 | if (retc = krb_rd_req(&authent, server_parm.sname, server_parm.sinst, |
---|
133 | server_parm.recv_addr.sin_addr.s_addr, &ad, (char *)0)) |
---|
134 | { |
---|
135 | errpkt(dat, dat_len,retc + krb_err_base); |
---|
136 | return retc + krb_err_base; |
---|
137 | } |
---|
138 | |
---|
139 | #define clr_cli_secrets() {memset((char *)sess_sched, 0, sizeof(sess_sched)); memset((char *)ad.session, 0, sizeof(ad.session));} |
---|
140 | |
---|
141 | /* These two lines used to be |
---|
142 | in_st = *dat + *dat_len - r_len; |
---|
143 | but that was miscompiled by the HP/UX 9.01 C compiler. */ |
---|
144 | in_st = *dat + *dat_len; |
---|
145 | in_st -= r_len; |
---|
146 | #ifdef NOENCRYPTION |
---|
147 | ncksum = 0; |
---|
148 | #else |
---|
149 | ncksum = quad_cksum(in_st, (unsigned KRB_INT32 *)0, (long) r_len, 0, &ad.session); |
---|
150 | #endif |
---|
151 | if (ncksum!=ad.checksum) { /* yow, are we correct yet */ |
---|
152 | clr_cli_secrets(); |
---|
153 | errpkt(dat, dat_len,KADM_BAD_CHK); |
---|
154 | return KADM_BAD_CHK; |
---|
155 | } |
---|
156 | #ifdef NOENCRYPTION |
---|
157 | memset(sess_sched, 0, sizeof(sess_sched)); |
---|
158 | #else |
---|
159 | des_key_sched(ad.session, sess_sched); |
---|
160 | #endif |
---|
161 | if (retc = (int) krb_rd_priv(in_st, r_len, sess_sched, &ad.session, |
---|
162 | &server_parm.recv_addr, |
---|
163 | &server_parm.admin_addr, &msg_st)) { |
---|
164 | clr_cli_secrets(); |
---|
165 | errpkt(dat, dat_len,retc + krb_err_base); |
---|
166 | return retc + krb_err_base; |
---|
167 | } |
---|
168 | switch (msg_st.app_data[0]) { |
---|
169 | case CHANGE_PW: |
---|
170 | retval = kadm_ser_cpw(msg_st.app_data+1,(int) msg_st.app_length-1,&ad, |
---|
171 | &retdat, &retlen); |
---|
172 | break; |
---|
173 | case ADD_ENT: |
---|
174 | retval = kadm_ser_add(msg_st.app_data+1,(int) msg_st.app_length-1,&ad, |
---|
175 | &retdat, &retlen); |
---|
176 | break; |
---|
177 | case DEL_ENT: |
---|
178 | retval = kadm_ser_del(msg_st.app_data+1,(int) msg_st.app_length-1,&ad, |
---|
179 | &retdat, &retlen); |
---|
180 | break; |
---|
181 | case GET_ENT: |
---|
182 | retval = kadm_ser_get(msg_st.app_data+1,(int) msg_st.app_length-1,&ad, |
---|
183 | &retdat, &retlen); |
---|
184 | break; |
---|
185 | case MOD_ENT: |
---|
186 | retval = kadm_ser_mod(msg_st.app_data+1,(int) msg_st.app_length-1,&ad, |
---|
187 | &retdat, &retlen); |
---|
188 | break; |
---|
189 | case CHECK_PW: |
---|
190 | retval = kadm_ser_ckpw(msg_st.app_data+1,(int) msg_st.app_length-1,&ad, |
---|
191 | &retdat, &retlen); |
---|
192 | break; |
---|
193 | default: |
---|
194 | clr_cli_secrets(); |
---|
195 | errpkt(dat, dat_len, KADM_NO_OPCODE); |
---|
196 | return KADM_NO_OPCODE; |
---|
197 | } |
---|
198 | /* Now seal the response back into a priv msg */ |
---|
199 | free((char *)*dat); |
---|
200 | tmpdat = (u_char *) malloc((unsigned)(retlen + KADM_VERSIZE + |
---|
201 | sizeof(retval))); |
---|
202 | (void) strncpy((char *)tmpdat, KADM_VERSTR, KADM_VERSIZE); |
---|
203 | retval = htonl((u_long)retval); |
---|
204 | memcpy((char *)tmpdat + KADM_VERSIZE, (char *)&retval, sizeof(retval)); |
---|
205 | if (retlen) { |
---|
206 | memcpy((char *)tmpdat + KADM_VERSIZE + sizeof(retval), (char *)retdat, |
---|
207 | retlen); |
---|
208 | free((char *)retdat); |
---|
209 | } |
---|
210 | /* slop for mk_priv stuff */ |
---|
211 | *dat = (u_char *) malloc((unsigned) (retlen + KADM_VERSIZE + |
---|
212 | sizeof(retval) + 200)); |
---|
213 | if ((*dat_len = krb_mk_priv(tmpdat, *dat, |
---|
214 | (u_long) (retlen + KADM_VERSIZE + |
---|
215 | sizeof(retval)), |
---|
216 | sess_sched, |
---|
217 | &ad.session, &server_parm.admin_addr, |
---|
218 | &server_parm.recv_addr)) < 0) { |
---|
219 | clr_cli_secrets(); |
---|
220 | errpkt(dat, dat_len, KADM_NO_ENCRYPT); |
---|
221 | return KADM_NO_ENCRYPT; |
---|
222 | } |
---|
223 | clr_cli_secrets(); |
---|
224 | return KADM_SUCCESS; |
---|
225 | } |
---|