1 | /* $Id: ticket.c,v 1.28 2009-12-29 17:29:34 zacheiss Exp $ |
---|
2 | * |
---|
3 | * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology. |
---|
4 | * For copying and distribution information, please see the file |
---|
5 | * <mit-copyright.h>. |
---|
6 | */ |
---|
7 | |
---|
8 | #include <mit-copyright.h> |
---|
9 | #include <moira.h> |
---|
10 | |
---|
11 | #include <sys/stat.h> |
---|
12 | |
---|
13 | #include <stdio.h> |
---|
14 | #include <string.h> |
---|
15 | |
---|
16 | #ifdef HAVE_KRB4 |
---|
17 | #include <krb.h> |
---|
18 | #else |
---|
19 | #define KTEXT void* |
---|
20 | #include <mr_krb.h> |
---|
21 | #endif |
---|
22 | #include <krb5.h> |
---|
23 | #include <update.h> |
---|
24 | |
---|
25 | RCSID("$Header: /afs/.athena.mit.edu/astaff/project/moiradev/repository/moira/update/ticket.c,v 1.28 2009-12-29 17:29:34 zacheiss Exp $"); |
---|
26 | |
---|
27 | static char realm[REALM_SZ]; |
---|
28 | static char master[INST_SZ] = "sms"; |
---|
29 | static char service[ANAME_SZ] = "rcmd"; |
---|
30 | #ifdef HAVE_KRB4 |
---|
31 | des_cblock session; |
---|
32 | #endif |
---|
33 | krb5_context context = NULL; |
---|
34 | |
---|
35 | static int get_mr_krb5_tgt(krb5_context context, krb5_ccache ccache); |
---|
36 | #ifdef HAVE_KRB4 |
---|
37 | static int get_mr_tgt(void); |
---|
38 | #endif |
---|
39 | |
---|
40 | int get_mr_krb5_update_ticket(char *host, krb5_data *auth) |
---|
41 | { |
---|
42 | krb5_auth_context auth_con = NULL; |
---|
43 | krb5_ccache ccache = NULL; |
---|
44 | krb5_error_code code; |
---|
45 | int pass = 1; |
---|
46 | |
---|
47 | code = krb5_init_context(&context); |
---|
48 | if (code) |
---|
49 | goto out; |
---|
50 | |
---|
51 | code = krb5_auth_con_init(context, &auth_con); |
---|
52 | if (code) |
---|
53 | goto out; |
---|
54 | |
---|
55 | code = krb5_cc_default(context, &ccache); |
---|
56 | if (code) |
---|
57 | goto out; |
---|
58 | |
---|
59 | try_it: |
---|
60 | code = krb5_mk_req(context, &auth_con, 0, "host", host, NULL, ccache, |
---|
61 | auth); |
---|
62 | if (code) |
---|
63 | { |
---|
64 | if (pass == 1) |
---|
65 | { |
---|
66 | if ((code = get_mr_krb5_tgt(context, ccache))) |
---|
67 | { |
---|
68 | com_err(whoami, code, "can't get Kerberos v5 TGT"); |
---|
69 | return code; |
---|
70 | } |
---|
71 | pass++; |
---|
72 | goto try_it; |
---|
73 | } |
---|
74 | com_err(whoami, code, "in krb5_mk_req"); |
---|
75 | } |
---|
76 | |
---|
77 | out: |
---|
78 | if (ccache) |
---|
79 | krb5_cc_close(context, ccache); |
---|
80 | if (auth_con) |
---|
81 | krb5_auth_con_free(context, auth_con); |
---|
82 | return code; |
---|
83 | } |
---|
84 | |
---|
85 | int get_mr_krb5_tgt(krb5_context context, krb5_ccache ccache) |
---|
86 | { |
---|
87 | krb5_creds my_creds; |
---|
88 | krb5_principal me = NULL; |
---|
89 | krb5_error_code code; |
---|
90 | |
---|
91 | memset(&my_creds, 0, sizeof(my_creds)); |
---|
92 | |
---|
93 | code = krb5_parse_name(context, master, &me); |
---|
94 | if (code) |
---|
95 | goto out; |
---|
96 | |
---|
97 | code = krb5_get_init_creds_keytab(context, &my_creds, me, NULL, 0, NULL, NULL); |
---|
98 | if (code) |
---|
99 | goto out; |
---|
100 | |
---|
101 | code = krb5_cc_initialize(context, ccache, me); |
---|
102 | if (code) |
---|
103 | goto out; |
---|
104 | |
---|
105 | code = krb5_cc_store_cred(context, ccache, &my_creds); |
---|
106 | if (code) |
---|
107 | goto out; |
---|
108 | |
---|
109 | out: |
---|
110 | if (me) |
---|
111 | krb5_free_principal(context, me); |
---|
112 | krb5_free_cred_contents(context, &my_creds); |
---|
113 | |
---|
114 | return code; |
---|
115 | } |
---|
116 | |
---|
117 | int get_mr_update_ticket(char *host, KTEXT ticket) |
---|
118 | { |
---|
119 | #ifdef HAVE_KRB4 |
---|
120 | int code, pass; |
---|
121 | char phost[BUFSIZ]; |
---|
122 | CREDENTIALS cr; |
---|
123 | |
---|
124 | pass = 1; |
---|
125 | if (krb_get_lrealm(realm, 1)) |
---|
126 | strcpy(realm, KRB_REALM); |
---|
127 | strcpy(phost, (char *)krb_get_phost(host)); |
---|
128 | |
---|
129 | try_it: |
---|
130 | code = krb_mk_req(ticket, service, phost, realm, (long)0); |
---|
131 | if (code) |
---|
132 | { |
---|
133 | if (pass == 1) |
---|
134 | { |
---|
135 | /* maybe we're taking too long? */ |
---|
136 | if ((code = get_mr_tgt())) |
---|
137 | { |
---|
138 | com_err(whoami, code, "can't get Kerberos TGT"); |
---|
139 | return code; |
---|
140 | } |
---|
141 | pass++; |
---|
142 | goto try_it; |
---|
143 | } |
---|
144 | code += ERROR_TABLE_BASE_krb; |
---|
145 | com_err(whoami, code, "in krb_mk_req"); |
---|
146 | } |
---|
147 | else |
---|
148 | { |
---|
149 | code = krb_get_cred(service, phost, realm, &cr); |
---|
150 | if (code) |
---|
151 | code += ERROR_TABLE_BASE_krb; |
---|
152 | memcpy(session, cr.session, sizeof(session)); |
---|
153 | } |
---|
154 | return code; |
---|
155 | #else |
---|
156 | return MR_NO_KRB4; |
---|
157 | #endif |
---|
158 | } |
---|
159 | |
---|
160 | #ifdef HAVE_KRB4 |
---|
161 | static int get_mr_tgt(void) |
---|
162 | { |
---|
163 | int code; |
---|
164 | char linst[INST_SZ], kinst[INST_SZ]; |
---|
165 | |
---|
166 | linst[0] = '\0'; |
---|
167 | strcpy(kinst, "krbtgt"); |
---|
168 | code = krb_get_svc_in_tkt(master, linst, realm, kinst, realm, |
---|
169 | DEFAULT_TKT_LIFE, KEYFILE); |
---|
170 | if (!code) |
---|
171 | return 0; |
---|
172 | else |
---|
173 | return code + ERROR_TABLE_BASE_krb; |
---|
174 | } |
---|
175 | #endif |
---|