source: trunk/third/cns/src/kadmin/kadm_server.c @ 8789

Revision 8789, 10.0 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8788, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright 1988 by the Massachusetts Institute of Technology.
3 *
4 * For copying and distribution information, please see the file
5 * <mit-copyright.h>.
6 *
7 * Kerberos administration server-side subroutines
8 */
9
10#include <mit-copyright.h>
11
12#include <string.h>
13
14#include <kadm.h>
15#include <kadm_err.h>
16
17int fascist_cpw = 0;            /* Be fascist about insecure passwords? */
18
19char bad_pw_err[] =
20        "\007\007\007ERROR: Insecure password not accepted.  Please choose another.\n\n";
21
22char bad_pw_warn[] =
23        "\007\007\007WARNING: You have chosen an insecure password.  You may wish to\nchoose a better password.\n\n";
24
25char check_pw_msg[] =
26        "You have entered an insecure password.  You should choose another.\n\n";
27
28char pw_blurb[] =
29        "A good password is something which is easy for you to remember, but\nthat people who know you won't easily guess.  Don't use a word found\nin the dictionary, because someone may run a program that tries all\nthose words.  That same program will probably try the names of all\nknown comic-strip characters, rock bands, etc.  Please do not let\nanyone else, including friends, know your password.  Remember, *YOU*\nare assumed to be responsible for anything done using your password.\n";
30
31/*
32kadm_ser_cpw - the server side of the change_password routine
33  recieves    : KTEXT, {key}
34  returns     : CKSUM, RETCODE
35  acl         : caller can change only own password
36
37Replaces the password (i.e. des key) of the caller with that specified in key.
38Returns no actual data from the master server, since this is called by a user
39*/
40kadm_ser_cpw(dat, len, ad, datout, outlen)
41u_char *dat;
42int len;
43AUTH_DAT *ad;
44u_char **datout;
45int *outlen;
46{
47    unsigned KRB_INT32 keylow, keyhigh;
48    char pword[MAX_KPW_LEN];
49    int no_pword = 0;
50    des_cblock newkey;
51    int status, stvlen = 0;
52    int retval;
53    extern char *malloc();
54    extern int kadm_approve_pw();
55
56    /* take key off the stream, and change the database */
57
58    if ((status = stv_long(dat, &keyhigh, 0, len)) < 0)
59        return(KADM_LENGTH_ERROR);
60    stvlen += status;
61    if ((status = stv_long(dat, &keylow, stvlen, len)) < 0)
62        return(KADM_LENGTH_ERROR);
63    stvlen += status;
64    if ((stvlen = stv_string(dat, pword, stvlen, sizeof(pword), len)) < 0) {
65        no_pword++;
66        pword[0]='\0';
67    }
68    stvlen += status;
69
70    keylow = ntohl(keylow);
71    keyhigh = ntohl(keyhigh);
72    memcpy((char *)(((KRB_INT32 *)newkey) + 1), (char *)&keyhigh, sizeof(KRB_INT32));
73    memcpy((char *)newkey, (char *)&keylow, sizeof(KRB_INT32));
74    if (retval = kadm_approve_pw(ad->pname, ad->pinst, ad->prealm,
75                        newkey, no_pword ? 0 : pword)) {
76            if (retval == KADM_PW_MISMATCH) {
77                    /*
78                     * Very strange!!!  This means that the cleartext
79                     * password which was sent and the DES cblock
80                     * didn't match!
81                     */
82                    (void) krb_log("'%s.%s@%s' sent a password string which didn't match with the DES key?!?",
83                               ad->pname, ad->pinst, ad->prealm);
84                    return(retval);
85            }
86            if (fascist_cpw) {
87                    *outlen = strlen(bad_pw_err)+strlen(pw_blurb)+1;
88                    if (*datout = (u_char *) malloc(*outlen)) {
89                            strcpy((char *) *datout, bad_pw_err);
90                            strcat((char *) *datout, pw_blurb);
91                    } else
92                            *outlen = 0;
93                    (void) krb_log("'%s.%s@%s' tried to use an insecure password in changepw",
94                               ad->pname, ad->pinst, ad->prealm);
95#ifdef notdef
96                    /* For debugging only, probably a bad idea */
97                    if (!no_pword)
98                            (void) krb_log("The password was %s\n", pword);
99#endif
100                    return(retval);
101            } else {
102                    *outlen = strlen(bad_pw_warn) + strlen(pw_blurb)+1;
103                    if (*datout = (u_char *) malloc(*outlen)) {
104                            strcpy((char *) *datout, bad_pw_warn);
105                            strcat((char *) *datout, pw_blurb);
106                    } else
107                            *outlen = 0;
108                    (void) krb_log("'%s.%s@%s' used an insecure password in changepw",
109                               ad->pname, ad->pinst, ad->prealm);
110            }
111    } else {
112            *datout = 0;
113            *outlen = 0;
114    }
115
116    return(kadm_change(ad->pname, ad->pinst, ad->prealm, newkey));
117}
118
119/*
120kadm_ser_add - the server side of the add_entry routine
121  recieves    : KTEXT, {values}
122  returns     : CKSUM, RETCODE, {values}
123  acl         : su, sms (as alloc)
124
125Adds and entry containing values to the database
126returns the values of the entry, so if you leave certain fields blank you will
127   be able to determine the default values they are set to
128*/
129kadm_ser_add(dat,len,ad, datout, outlen)
130u_char *dat;
131int len;
132AUTH_DAT *ad;
133u_char **datout;
134int *outlen;
135{
136  Kadm_vals values, retvals;
137  int status;
138
139  if ((status = stream_to_vals(dat, &values, len)) < 0)
140      return(KADM_LENGTH_ERROR);
141  if ((status = kadm_add_entry(ad->pname, ad->pinst, ad->prealm,
142                              &values, &retvals)) == KADM_DATA) {
143      *outlen = vals_to_stream(&retvals,datout);
144      return KADM_SUCCESS;
145  } else {
146      *outlen = 0;
147      return status;
148  }
149}
150
151/*
152kadm_ser_del - the server side of the del_entry routine
153  recieves    : KTEXT, {values}
154  returns     : CKSUM, RETCODE, {values}
155  acl         : su, sms (as alloc)
156
157Deletess an entry containing values to the database
158returns the values of the entry, so if you leave certain fields blank you will
159   be able to determine the default values they are set to
160*/
161kadm_ser_del(dat,len,ad, datout, outlen)
162u_char *dat;
163int len;
164AUTH_DAT *ad;
165u_char **datout;
166int *outlen;
167{
168  Kadm_vals values, retvals;
169  int status;
170
171  if ((status = stream_to_vals(dat, &values, len)) < 0)
172      return(KADM_LENGTH_ERROR);
173  if ((status = kadm_del_entry(ad->pname, ad->pinst, ad->prealm,
174                              &values, &retvals)) == KADM_DATA) {
175      *outlen = vals_to_stream(&retvals,datout);
176      return KADM_SUCCESS;
177  } else {
178      *outlen = 0;
179      return status;
180  }
181}
182
183/*
184kadm_ser_mod - the server side of the mod_entry routine
185  recieves    : KTEXT, {values, values}
186  returns     : CKSUM, RETCODE, {values}
187  acl         : su, sms (as register or dealloc)
188
189Modifies all entries corresponding to the first values so they match the
190   second values.
191returns the values for the changed entries
192*/
193kadm_ser_mod(dat,len,ad, datout, outlen)
194u_char *dat;
195int len;
196AUTH_DAT *ad;
197u_char **datout;
198int *outlen;
199{
200  Kadm_vals vals1, vals2, retvals;
201  int wh;
202  int status;
203
204  if ((wh = stream_to_vals(dat, &vals1, len)) < 0)
205      return KADM_LENGTH_ERROR;
206  if ((status = stream_to_vals(dat+wh,&vals2, len-wh)) < 0)
207      return KADM_LENGTH_ERROR;
208  if ((status = kadm_mod_entry(ad->pname, ad->pinst, ad->prealm, &vals1,
209                               &vals2, &retvals)) == KADM_DATA) {
210      *outlen = vals_to_stream(&retvals,datout);
211      return KADM_SUCCESS;
212  } else {
213      *outlen = 0;
214      return status;
215  }
216}
217
218/*
219kadm_ser_get
220  recieves   : KTEXT, {values, flags}
221  returns    : CKSUM, RETCODE, {count, values, values, values}
222  acl        : su
223
224gets the fields requested by flags from all entries matching values
225returns this data for each matching recipient, after a count of how many such
226  matches there were
227*/
228kadm_ser_get(dat,len,ad, datout, outlen)
229u_char *dat;
230int len;
231AUTH_DAT *ad;
232u_char **datout;
233int *outlen;
234{
235  Kadm_vals values, retvals;
236  u_char fl[FLDSZ];
237  int loop,wh;
238  int status;
239
240  if ((wh = stream_to_vals(dat, &values, len)) < 0)
241      return KADM_LENGTH_ERROR;
242  if (wh + FLDSZ > len)
243      return KADM_LENGTH_ERROR;
244  for (loop=FLDSZ-1; loop>=0; loop--)
245    fl[loop] = dat[wh++];
246  if ((status = kadm_get_entry(ad->pname, ad->pinst, ad->prealm,
247                              &values, fl, &retvals)) == KADM_DATA) {
248      *outlen = vals_to_stream(&retvals,datout);
249      return KADM_SUCCESS;
250  } else {
251      *outlen = 0;
252      return status;
253  }
254}
255
256/*
257kadm_ser_ckpw - the server side of the check_password routine
258  recieves    : KTEXT, {key}
259  returns     : CKSUM, RETCODE
260  acl         : none
261
262Checks to see if the des key passed from the caller is a "secure" password.
263*/
264kadm_ser_ckpw(dat, len, ad, datout, outlen)
265u_char *dat;
266int len;
267AUTH_DAT *ad;
268u_char **datout;
269int *outlen;
270{
271    unsigned KRB_INT32 keylow, keyhigh;
272    char pword[MAX_KPW_LEN];
273    int no_pword = 0;
274    des_cblock newkey;
275    int stvlen;
276    int retval;
277    extern char *malloc();
278    extern int kadm_approve_pw();
279
280    /* take key off the stream, and check it */
281
282    if ((stvlen = stv_long(dat, &keyhigh, 0, len)) < 0)
283        return(KADM_LENGTH_ERROR);
284    if ((stvlen = stv_long(dat, &keylow, stvlen, len)) < 0)
285        return(KADM_LENGTH_ERROR);
286    if ((stvlen = stv_string(dat, pword, stvlen, sizeof(pword), len)) < 0) {
287        no_pword++;
288        pword[0]='\0';
289    }
290
291    keylow = ntohl(keylow);
292    keyhigh = ntohl(keyhigh);
293    memcpy((char *)(((KRB_INT32 *)newkey) + 1), (char *)&keyhigh, sizeof(KRB_INT32));
294    memcpy((char *)newkey, (char *)&keylow, sizeof(KRB_INT32));
295    if (retval = kadm_approve_pw(ad->pname, ad->pinst, ad->prealm, newkey,
296                        no_pword ? 0 : pword)) {
297            *outlen = strlen(check_pw_msg)+strlen(pw_blurb)+1;
298            if (*datout = (u_char *) malloc(*outlen)) {
299                    strcpy((char *) *datout, check_pw_msg);
300                    strcat((char *) *datout, pw_blurb);
301            } else
302                    *outlen = 0;
303            (void) krb_log("'%s.%s@%s' sent an insecure password to be checked",
304                       ad->pname, ad->pinst, ad->prealm);
305            return(retval);
306    } else {
307            *datout = 0;
308            *outlen = 0;
309            (void) krb_log("'%s.%s@%s' sent a secure password to be checked",
310                       ad->pname, ad->pinst, ad->prealm);
311    }
312    return(0);
313}
314
315
316/*
317kadm_ser_stab - the server side of the change_srvtab routine
318  recieves    : KTEXT, {values}
319  returns     : CKSUM, RETCODE, {values}
320  acl         : su, sms (as register or dealloc)
321
322Creates or modifies the specified service principal to have a random
323key, which is sent back to the client.  The key version is returned in
324the max_life field of the values structure.  It's a hack, but it's a
325backwards compatible hack....
326*/
327kadm_ser_stab(dat, len, ad, datout, outlen)
328u_char *dat;
329int len;
330AUTH_DAT *ad;
331u_char **datout;
332int *outlen;
333{
334  Kadm_vals values;
335  int status;
336
337  if ((status = stream_to_vals(dat, &values, len)) < 0)
338          return KADM_LENGTH_ERROR;
339  status = kadm_chg_srvtab(ad->pname, ad->pinst, ad->prealm, &values);
340  if (status == KADM_DATA) {
341      *outlen = vals_to_stream(&values,datout);
342      values.key_low = values.key_high = 0;
343      return KADM_SUCCESS;
344  } else {
345      *outlen = 0;
346      return status;
347  }
348}
Note: See TracBrowser for help on using the repository browser.