Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/clients/ksu/krb_auth_su.c
34889 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/*
3
* Copyright (c) 1994 by the University of Southern California
4
*
5
* EXPORT OF THIS SOFTWARE from the United States of America may
6
* require a specific license from the United States Government.
7
* It is the responsibility of any person or organization contemplating
8
* export to obtain such a license before exporting.
9
*
10
* WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute
11
* this software and its documentation in source and binary forms is
12
* hereby granted, provided that any documentation or other materials
13
* related to such distribution or use acknowledge that the software
14
* was developed by the University of Southern California.
15
*
16
* DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The
17
* University of Southern California MAKES NO REPRESENTATIONS OR
18
* WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not
19
* limitation, the University of Southern California MAKES NO
20
* REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
21
* PARTICULAR PURPOSE. The University of Southern
22
* California shall not be held liable for any liability nor for any
23
* direct, indirect, or consequential damages with respect to any
24
* claim by the user or distributor of the ksu software.
25
*
26
* KSU was written by: Ari Medvinsky, [email protected]
27
*/
28
29
#include "ksu.h"
30
31
32
void plain_dump_principal(krb5_context, krb5_principal);
33
34
krb5_boolean
35
krb5_auth_check(krb5_context context, krb5_principal client_pname,
36
char *hostname, krb5_get_init_creds_opt *options,
37
char *target_user, krb5_ccache cc, int *path_passwd,
38
uid_t target_uid)
39
{
40
krb5_principal client = NULL;
41
krb5_verify_init_creds_opt vfy_opts;
42
krb5_creds tgt = { 0 }, tgtq = { 0 };
43
krb5_error_code retval =0;
44
int got_it = 0;
45
krb5_boolean zero_password;
46
krb5_boolean ok = FALSE;
47
48
*path_passwd = 0;
49
50
if ((retval= krb5_copy_principal(context, client_pname, &client))){
51
com_err(prog_name, retval, _("while copying client principal"));
52
goto cleanup;
53
}
54
55
if ((retval= krb5_copy_principal(context, client, &tgtq.client))){
56
com_err(prog_name, retval, _("while copying client principal"));
57
goto cleanup;
58
}
59
60
if ((retval = ksu_tgtname(context, krb5_princ_realm(context, client),
61
krb5_princ_realm(context, client),
62
&tgtq.server))){
63
com_err(prog_name, retval, _("while creating tgt for local realm"));
64
goto cleanup;
65
}
66
67
if (auth_debug){ dump_principal(context, "local tgt principal name", tgtq.server ); }
68
retval = krb5_cc_retrieve_cred(context, cc,
69
KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES,
70
&tgtq, &tgt);
71
72
if (! retval) retval = krb5_check_exp(context, tgt.times);
73
74
if (retval){
75
if ((retval != KRB5_CC_NOTFOUND) &&
76
(retval != KRB5KRB_AP_ERR_TKT_EXPIRED)){
77
com_err(prog_name, retval, _("while retrieving creds from cache"));
78
goto cleanup;
79
}
80
} else{
81
got_it = 1;
82
}
83
84
if (! got_it){
85
86
#ifdef GET_TGT_VIA_PASSWD
87
if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
88
com_err("ksu", errno, _("while switching to target uid"));
89
goto cleanup;
90
}
91
92
93
fprintf(stderr, _("WARNING: Your password may be exposed if you enter "
94
"it here and are logged \n"));
95
fprintf(stderr, _(" in remotely using an unsecure "
96
"(non-encrypted) channel. \n"));
97
98
/*get the ticket granting ticket, via passwd(prompt for passwd)*/
99
if (ksu_get_tgt_via_passwd(context, client, options, &zero_password,
100
&tgt) == FALSE) {
101
krb5_seteuid(0);
102
103
goto cleanup;
104
}
105
*path_passwd = 1;
106
if (krb5_seteuid(0)) {
107
com_err("ksu", errno, _("while reclaiming root uid"));
108
goto cleanup;
109
}
110
111
#else
112
plain_dump_principal (context, client);
113
fprintf(stderr,
114
_("does not have any appropriate tickets in the cache.\n"));
115
goto cleanup;
116
117
#endif /* GET_TGT_VIA_PASSWD */
118
119
}
120
121
krb5_verify_init_creds_opt_init(&vfy_opts);
122
krb5_verify_init_creds_opt_set_ap_req_nofail( &vfy_opts, 1);
123
retval = krb5_verify_init_creds(context, &tgt, NULL, NULL, NULL,
124
&vfy_opts);
125
if (retval) {
126
com_err(prog_name, retval, _("while verifying ticket for server"));
127
goto cleanup;
128
}
129
130
ok = TRUE;
131
132
cleanup:
133
krb5_free_principal(context, client);
134
krb5_free_cred_contents(context, &tgt);
135
krb5_free_cred_contents(context, &tgtq);
136
return ok;
137
}
138
139
krb5_boolean
140
ksu_get_tgt_via_passwd(krb5_context context, krb5_principal client,
141
krb5_get_init_creds_opt *options,
142
krb5_boolean *zero_password, krb5_creds *creds_out)
143
{
144
krb5_boolean ok = FALSE;
145
krb5_error_code code;
146
krb5_creds creds = { 0 };
147
krb5_timestamp now;
148
unsigned int pwsize;
149
char password[255], prompt[255], *client_name = NULL;
150
int result;
151
152
*zero_password = FALSE;
153
if (creds_out != NULL)
154
memset(creds_out, 0, sizeof(*creds_out));
155
156
if ((code = krb5_unparse_name(context, client, &client_name))) {
157
com_err (prog_name, code, _("when unparsing name"));
158
goto cleanup;
159
}
160
161
memset(&creds, 0, sizeof(creds));
162
163
if ((code = krb5_timeofday(context, &now))) {
164
com_err(prog_name, code, _("while getting time of day"));
165
goto cleanup;
166
}
167
168
result = snprintf(prompt, sizeof(prompt), _("Kerberos password for %s: "),
169
client_name);
170
if (SNPRINTF_OVERFLOW(result, sizeof(prompt))) {
171
fprintf(stderr,
172
_("principal name %s too long for internal buffer space\n"),
173
client_name);
174
goto cleanup;
175
}
176
177
pwsize = sizeof(password);
178
179
code = krb5_read_password(context, prompt, 0, password, &pwsize);
180
if (code ) {
181
com_err(prog_name, code, _("while reading password for '%s'\n"),
182
client_name);
183
goto cleanup;
184
}
185
186
if ( pwsize == 0) {
187
fprintf(stderr, _("No password given\n"));
188
*zero_password = TRUE;
189
goto cleanup;
190
}
191
192
code = krb5_get_init_creds_password(context, &creds, client, password,
193
krb5_prompter_posix, NULL, 0, NULL,
194
options);
195
zap(password, sizeof(password));
196
197
198
if (code) {
199
if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
200
fprintf(stderr, _("%s: Password incorrect\n"), prog_name);
201
else
202
com_err(prog_name, code, _("while getting initial credentials"));
203
goto cleanup;
204
}
205
if (creds_out != NULL) {
206
*creds_out = creds;
207
memset(&creds, 0, sizeof(creds));
208
}
209
210
ok = TRUE;
211
212
cleanup:
213
krb5_free_cred_contents(context, &creds);
214
free(client_name);
215
return ok;
216
}
217
218
void
219
dump_principal(krb5_context context, char *str, krb5_principal p)
220
{
221
char * stname;
222
krb5_error_code retval;
223
224
if ((retval = krb5_unparse_name(context, p, &stname))) {
225
fprintf(stderr, _(" %s while unparsing name\n"),
226
error_message(retval));
227
return;
228
}
229
fprintf(stderr, " %s: %s\n", str, stname);
230
free(stname);
231
}
232
233
void
234
plain_dump_principal (krb5_context context, krb5_principal p)
235
{
236
char * stname;
237
krb5_error_code retval;
238
239
if ((retval = krb5_unparse_name(context, p, &stname))) {
240
fprintf(stderr, _(" %s while unparsing name\n"),
241
error_message(retval));
242
return;
243
}
244
fprintf(stderr, "%s ", stname);
245
free(stname);
246
}
247
248