1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <pwd.h>
27 #include <locale.h>
28 #include <syslog.h>
29 #include <errno.h>
30 #include <com_err.h>
31 #include <k5-int.h>
32 
33 extern uint_t kwarn_add_warning(char *, int);
34 extern uint_t kwarn_del_warning(char *);
35 
36 /*
37  * Store the forwarded creds in the user's local ccache and register
38  * w/ktkt_warnd(8).
39  */
40 krb5_error_code
store_forw_creds(krb5_context context,krb5_creds ** creds,krb5_ticket * ticket,char * lusername,krb5_ccache * ccache)41 store_forw_creds(krb5_context context,
42 		    krb5_creds **creds,
43 		    krb5_ticket *ticket,
44 		    char *lusername,
45 		    krb5_ccache *ccache)
46 {
47 	krb5_error_code retval;
48 	char ccname[MAXPATHLEN];
49 	struct passwd *pwd;
50 	uid_t uid;
51 	char *client_name = NULL;
52 
53 	*ccache = NULL;
54 	if (!(pwd = getpwnam(lusername)))
55 		return (ENOENT);
56 
57 	uid = getuid();
58 	if (seteuid(pwd->pw_uid))
59 		return (-1);
60 
61 	(void) snprintf(ccname, sizeof (ccname), "FILE:/tmp/krb5cc_%ld",
62 	    pwd->pw_uid);
63 
64 	if ((retval = krb5_cc_resolve(context, ccname, ccache)) != 0) {
65 		krb5_set_error_message(context, retval,
66 		    gettext("failed to resolve cred cache %s"), ccname);
67 		goto cleanup;
68 	}
69 
70 	if ((retval = krb5_cc_initialize(context, *ccache,
71 	    ticket->enc_part2->client)) != 0) {
72 		krb5_set_error_message(context, retval,
73 		    gettext("failed to initialize cred cache %s"), ccname);
74 		goto cleanup;
75 	}
76 
77 	if ((retval = krb5_cc_store_cred(context, *ccache, *creds)) != 0) {
78 		krb5_set_error_message(context, retval,
79 		    gettext("failed to store cred in cache %s"), ccname);
80 		goto cleanup;
81 	}
82 
83 	if ((retval = krb5_cc_close(context, *ccache)) != 0)
84 		goto cleanup;
85 
86 	/* Register with ktkt_warnd(8) */
87 	if ((retval = krb5_unparse_name(context, (*creds)->client,
88 	    &client_name)) != 0)
89 		goto cleanup;
90 	(void) kwarn_del_warning(client_name);
91 	if (kwarn_add_warning(client_name, (*creds)->times.endtime) != 0) {
92 		syslog(LOG_AUTH|LOG_NOTICE,
93 		    "store_forw_creds: kwarn_add_warning"
94 		    " failed: ktkt_warnd(8) down? ");
95 	}
96 	free(client_name);
97 	client_name = NULL;
98 
99 cleanup:
100 	(void) seteuid(uid);
101 
102 	return (retval);
103 }
104