Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/windows/ms2mit/ms2mit.c
34907 views
1
/* windows/ms2mit/ms2mit.c */
2
/*
3
* Copyright (C) 2003 by the Massachusetts Institute of Technology.
4
* All rights reserved.
5
*
6
* Export of this software from the United States of America may
7
* require a specific license from the United States Government.
8
* It is the responsibility of any person or organization contemplating
9
* export to obtain such a license before exporting.
10
*
11
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12
* distribute this software and its documentation for any purpose and
13
* without fee is hereby granted, provided that the above copyright
14
* notice appear in all copies and that both that copyright notice and
15
* this permission notice appear in supporting documentation, and that
16
* the name of M.I.T. not be used in advertising or publicity pertaining
17
* to distribution of the software without specific, written prior
18
* permission. Furthermore if you modify this software you must label
19
* your software as modified software and not distribute it in such a
20
* fashion that it might be confused with the original M.I.T. software.
21
* M.I.T. makes no representations about the suitability of
22
* this software for any purpose. It is provided "as is" without express
23
* or implied warranty.
24
*/
25
26
#include "k5-int.h"
27
#include "krb5.h"
28
#include <stdio.h>
29
#include <string.h>
30
#include <time.h>
31
32
static char *prog;
33
34
static void
35
xusage(void)
36
{
37
fprintf(stderr, "xusage: %s [-c ccache]\n", prog);
38
exit(1);
39
}
40
41
/* Return true if princ is a local (not cross-realm) krbtgt principal. */
42
krb5_boolean
43
is_local_tgt(krb5_principal princ)
44
{
45
return princ->length == 2 &&
46
data_eq_string(princ->data[0], KRB5_TGS_NAME) &&
47
data_eq(princ->realm, princ->data[1]);
48
}
49
50
/*
51
* Check if a ccache has any tickets.
52
*/
53
static krb5_error_code
54
cc_has_tickets(krb5_context kcontext, krb5_ccache ccache, int *has_tickets)
55
{
56
krb5_error_code code;
57
krb5_cc_cursor cursor;
58
krb5_creds creds;
59
krb5_timestamp now = time(0);
60
61
*has_tickets = 0;
62
63
code = krb5_cc_set_flags(kcontext, ccache, KRB5_TC_NOTICKET);
64
if (code)
65
return code;
66
67
code = krb5_cc_start_seq_get(kcontext, ccache, &cursor);
68
if (code)
69
return code;
70
71
while (!*has_tickets) {
72
code = krb5_cc_next_cred(kcontext, ccache, &cursor, &creds);
73
if (code)
74
break;
75
76
if (!krb5_is_config_principal(kcontext, creds.server) &&
77
ts_after(creds.times.endtime, now))
78
*has_tickets = 1;
79
80
krb5_free_cred_contents(kcontext, &creds);
81
}
82
krb5_cc_end_seq_get(kcontext, ccache, &cursor);
83
84
return 0;
85
}
86
87
int
88
main(int argc, char *argv[])
89
{
90
krb5_context kcontext = NULL;
91
krb5_error_code code;
92
krb5_ccache ccache=NULL;
93
krb5_ccache mslsa_ccache=NULL;
94
krb5_cc_cursor cursor;
95
krb5_creds creds;
96
krb5_principal princ = NULL;
97
int found_tgt = 0;
98
int has_tickets;
99
int option;
100
char * ccachestr = 0;
101
102
prog = strrchr(argv[0], '/');
103
prog = prog ? (prog + 1) : argv[0];
104
105
while ((option = getopt(argc, argv, "c:h")) != -1) {
106
switch (option) {
107
case 'c':
108
ccachestr = optarg;
109
break;
110
case 'h':
111
default:
112
xusage();
113
break;
114
}
115
}
116
117
if (code = krb5_init_context(&kcontext)) {
118
com_err(argv[0], code, "while initializing kerberos library");
119
goto cleanup;
120
}
121
122
if (code = krb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) {
123
com_err(argv[0], code, "while opening MS LSA ccache");
124
goto cleanup;
125
}
126
127
/* Enumerate tickets from cache looking for a TGT */
128
if ((code = krb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor))) {
129
com_err(argv[0], code, "while initiating the cred sequence of MS LSA ccache");
130
goto cleanup;
131
}
132
133
while (!found_tgt) {
134
code = krb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds);
135
if (code)
136
break;
137
138
/* Check if the ticket is a TGT */
139
if (is_local_tgt(creds.server))
140
found_tgt = 1;
141
142
krb5_free_cred_contents(kcontext, &creds);
143
}
144
krb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor);
145
146
if (!found_tgt) {
147
fprintf(stderr, "%s: Initial Ticket Getting Tickets are not available from the MS LSA\n",
148
argv[0]);
149
/* Only set the LSA cache as the default if it actually has tickets. */
150
code = cc_has_tickets(kcontext, mslsa_ccache, &has_tickets);
151
if (code)
152
goto cleanup;
153
154
if (has_tickets)
155
code = krb5int_cc_user_set_default_name(kcontext, "MSLSA:");
156
157
goto cleanup;
158
}
159
160
if (code = krb5_cc_get_principal(kcontext, mslsa_ccache, &princ)) {
161
com_err(argv[0], code, "while obtaining MS LSA principal");
162
goto cleanup;
163
}
164
165
if (ccachestr)
166
code = krb5_cc_resolve(kcontext, ccachestr, &ccache);
167
else
168
code = krb5_cc_resolve(kcontext, "API:", &ccache);
169
if (code) {
170
com_err(argv[0], code, "while getting default ccache");
171
goto cleanup;
172
}
173
if (code = krb5_cc_initialize(kcontext, ccache, princ)) {
174
com_err (argv[0], code, "when initializing ccache");
175
goto cleanup;
176
}
177
178
if (code = krb5_cc_copy_creds(kcontext, mslsa_ccache, ccache)) {
179
com_err (argv[0], code, "while copying MS LSA ccache to default ccache");
180
goto cleanup;
181
}
182
183
/* Don't try and set the default cache if the cache name was specified. */
184
if (ccachestr == NULL) {
185
/* On success set the default cache to API. */
186
code = krb5int_cc_user_set_default_name(kcontext, "API:");
187
if (code) {
188
com_err(argv[0], code, "when setting default to API");
189
goto cleanup;
190
}
191
}
192
193
cleanup:
194
krb5_free_principal(kcontext, princ);
195
if (ccache != NULL)
196
krb5_cc_close(kcontext, ccache);
197
if (mslsa_ccache != NULL)
198
krb5_cc_close(kcontext, mslsa_ccache);
199
krb5_free_context(kcontext);
200
return code ? 1 : 0;
201
}
202
203