17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate * lib/krb5/krb/srv_rcache.c
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Copyright 1991 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate * All Rights Reserved.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
177c478bd9Sstevel@tonic-gate *
187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
307c478bd9Sstevel@tonic-gate * or implied warranty.
317c478bd9Sstevel@tonic-gate *
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * Allocate & prepare a default replay cache for a server.
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
36*159d09a2SMark Phalan #include "k5-int.h"
377c478bd9Sstevel@tonic-gate #include <ctype.h>
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate
40*159d09a2SMark Phalan /* Macro for valid RC name characters*/
41505d05c7Sgtb #define isvalidrcname(x) ((!ispunct(x))&&isgraph(x))
42505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_server_rcache(krb5_context context,const krb5_data * piece,krb5_rcache * rcptr)43505d05c7Sgtb krb5_get_server_rcache(krb5_context context, const krb5_data *piece,
44505d05c7Sgtb krb5_rcache *rcptr)
457c478bd9Sstevel@tonic-gate {
467c478bd9Sstevel@tonic-gate krb5_rcache rcache = 0;
47505d05c7Sgtb char *cachename = 0, *def_env = 0, *cachetype;
484ef135ebSsemery char tmp[4], *full_name;
497c478bd9Sstevel@tonic-gate krb5_error_code retval;
50505d05c7Sgtb int p, i;
51505d05c7Sgtb unsigned int len;
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate #ifdef HAVE_GETEUID
547c478bd9Sstevel@tonic-gate unsigned long tens;
557c478bd9Sstevel@tonic-gate unsigned long uid = geteuid();
567c478bd9Sstevel@tonic-gate #endif
577c478bd9Sstevel@tonic-gate
58505d05c7Sgtb if (piece == NULL)
597c478bd9Sstevel@tonic-gate return ENOMEM;
607c478bd9Sstevel@tonic-gate
614ef135ebSsemery cachetype = krb5_rc_default_type(context);
624ef135ebSsemery
637c478bd9Sstevel@tonic-gate /*
64*159d09a2SMark Phalan * Solaris Kerberos: Check to see if something other than the default replay
65*159d09a2SMark Phalan * cache name will be used. If so then skip over the construction of
667c478bd9Sstevel@tonic-gate * said name.
677c478bd9Sstevel@tonic-gate */
687c478bd9Sstevel@tonic-gate if ((def_env = krb5_rc_default_name(context)) != 0) {
697c478bd9Sstevel@tonic-gate cachename = strdup(def_env);
704ef135ebSsemery if (cachename == NULL)
717c478bd9Sstevel@tonic-gate return (ENOMEM);
724ef135ebSsemery /*
734ef135ebSsemery * We expect to have the fully qualified rcache name (<type>:<name>),
744ef135ebSsemery * so we populate the default type here if the type is missing.
754ef135ebSsemery */
764ef135ebSsemery if (strchr(cachename, ':') == NULL) {
774ef135ebSsemery full_name = malloc(strlen(cachetype) + 1 +
784ef135ebSsemery strlen(cachename) + 1);
794ef135ebSsemery if (full_name == NULL) {
804ef135ebSsemery free(cachename);
814ef135ebSsemery return(ENOMEM);
824ef135ebSsemery }
834ef135ebSsemery (void) sprintf(full_name, "%s:%s", cachetype, cachename);
844ef135ebSsemery free(cachename);
854ef135ebSsemery cachename = full_name;
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate goto skip_create;
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate len = piece->length + 3 + 1;
917c478bd9Sstevel@tonic-gate for (i = 0; i < piece->length; i++) {
92505d05c7Sgtb if (piece->data[i] == '-')
937c478bd9Sstevel@tonic-gate len++;
94505d05c7Sgtb else if (!isvalidrcname((int) piece->data[i]))
957c478bd9Sstevel@tonic-gate len += 3;
967c478bd9Sstevel@tonic-gate }
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate #ifdef HAVE_GETEUID
997c478bd9Sstevel@tonic-gate len += 2; /* _<uid> */
1007c478bd9Sstevel@tonic-gate for (tens = 1; (uid / tens) > 9 ; tens *= 10)
1017c478bd9Sstevel@tonic-gate len++;
1027c478bd9Sstevel@tonic-gate #endif
1037c478bd9Sstevel@tonic-gate
104505d05c7Sgtb cachename = malloc(strlen(cachetype) + 5 + len);
1057c478bd9Sstevel@tonic-gate if (!cachename) {
1067c478bd9Sstevel@tonic-gate retval = ENOMEM;
1077c478bd9Sstevel@tonic-gate goto cleanup;
1087c478bd9Sstevel@tonic-gate }
109505d05c7Sgtb strcpy(cachename, cachetype);
110505d05c7Sgtb
111505d05c7Sgtb p = strlen(cachename);
112505d05c7Sgtb cachename[p++] = ':';
1137c478bd9Sstevel@tonic-gate for (i = 0; i < piece->length; i++) {
114505d05c7Sgtb if (piece->data[i] == '-') {
115505d05c7Sgtb cachename[p++] = '-';
116505d05c7Sgtb cachename[p++] = '-';
1177c478bd9Sstevel@tonic-gate continue;
1187c478bd9Sstevel@tonic-gate }
119505d05c7Sgtb if (!isvalidrcname((int) piece->data[i])) {
1207c478bd9Sstevel@tonic-gate sprintf(tmp, "%03o", piece->data[i]);
121505d05c7Sgtb cachename[p++] = '-';
1227c478bd9Sstevel@tonic-gate cachename[p++] = tmp[0];
1237c478bd9Sstevel@tonic-gate cachename[p++] = tmp[1];
1247c478bd9Sstevel@tonic-gate cachename[p++] = tmp[2];
1257c478bd9Sstevel@tonic-gate continue;
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate cachename[p++] = piece->data[i];
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate #ifdef HAVE_GETEUID
1317c478bd9Sstevel@tonic-gate cachename[p++] = '_';
1327c478bd9Sstevel@tonic-gate while (tens) {
1337c478bd9Sstevel@tonic-gate cachename[p++] = '0' + ((uid / tens) % 10);
1347c478bd9Sstevel@tonic-gate tens /= 10;
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate #endif
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate cachename[p++] = '\0';
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate skip_create:
141505d05c7Sgtb retval = krb5_rc_resolve_full(context, &rcache, cachename);
142e49962a0Ssemery if (retval) {
143e49962a0Ssemery rcache = 0;
1447c478bd9Sstevel@tonic-gate goto cleanup;
145e49962a0Ssemery }
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate /*
1487c478bd9Sstevel@tonic-gate * First try to recover the replay cache; if that doesn't work,
1497c478bd9Sstevel@tonic-gate * initialize it.
1507c478bd9Sstevel@tonic-gate */
151505d05c7Sgtb retval = krb5_rc_recover_or_initialize(context, rcache, context->clockskew);
1527c478bd9Sstevel@tonic-gate if (retval) {
153505d05c7Sgtb krb5_rc_close(context, rcache);
1547c478bd9Sstevel@tonic-gate rcache = 0;
1557c478bd9Sstevel@tonic-gate goto cleanup;
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate *rcptr = rcache;
1597c478bd9Sstevel@tonic-gate rcache = 0;
1607c478bd9Sstevel@tonic-gate retval = 0;
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate cleanup:
1637c478bd9Sstevel@tonic-gate if (rcache)
1647c478bd9Sstevel@tonic-gate krb5_xfree(rcache);
1657c478bd9Sstevel@tonic-gate if (cachename)
1667c478bd9Sstevel@tonic-gate krb5_xfree(cachename);
1677c478bd9Sstevel@tonic-gate return retval;
1687c478bd9Sstevel@tonic-gate }
169