Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/clients/kpasswd/kpasswd.c
34907 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
3
#include "k5-platform.h"
4
#include <locale.h>
5
#include <sys/types.h>
6
7
#ifndef _WIN32
8
#include <unistd.h>
9
#endif
10
11
#include <krb5.h>
12
13
#define P1 _("Enter new password")
14
#define P2 _("Enter it again")
15
16
#ifdef HAVE_PWD_H
17
#include <pwd.h>
18
19
static void
20
get_name_from_passwd_file(char *program_name, krb5_context context,
21
krb5_principal *me)
22
{
23
struct passwd *pw;
24
krb5_error_code ret;
25
26
pw = getpwuid(getuid());
27
if (pw != NULL) {
28
ret = krb5_parse_name(context, pw->pw_name, me);
29
if (ret) {
30
com_err(program_name, ret, _("when parsing name %s"), pw->pw_name);
31
exit(1);
32
}
33
} else {
34
fprintf(stderr, _("Unable to identify user from password file\n"));
35
exit(1);
36
}
37
}
38
#else /* HAVE_PWD_H */
39
static void
40
get_name_from_passwd_file(char *program_name, krb5_context context,
41
krb5_principal *me)
42
{
43
fprintf(stderr, _("Unable to identify user\n"));
44
exit(1);
45
}
46
#endif /* HAVE_PWD_H */
47
48
int main(int argc, char *argv[])
49
{
50
krb5_error_code ret;
51
krb5_context context;
52
krb5_principal princ = NULL;
53
char *pname, *message;
54
char pw[1024];
55
krb5_ccache ccache;
56
krb5_get_init_creds_opt *opts = NULL;
57
krb5_creds creds;
58
unsigned int pwlen;
59
int result_code;
60
krb5_data result_code_string, result_string;
61
62
setlocale(LC_ALL, "");
63
if (argc > 2) {
64
fprintf(stderr, _("usage: %s [principal]\n"), argv[0]);
65
exit(1);
66
}
67
68
pname = argv[1];
69
70
ret = krb5_init_context(&context);
71
if (ret) {
72
com_err(argv[0], ret, _("initializing kerberos library"));
73
exit(1);
74
}
75
ret = krb5_get_init_creds_opt_alloc(context, &opts);
76
if (ret) {
77
com_err(argv[0], ret, _("allocating krb5_get_init_creds_opt"));
78
exit(1);
79
}
80
81
/*
82
* In order, use the first of:
83
* - A name specified on the command line
84
* - The principal name from an existing ccache
85
* - The name corresponding to the ruid of the process
86
*
87
* Otherwise, it's an error.
88
* We always attempt to open the default ccache in order to use FAST if
89
* possible.
90
*/
91
ret = krb5_cc_default(context, &ccache);
92
if (ret) {
93
com_err(argv[0], ret, _("opening default ccache"));
94
exit(1);
95
}
96
ret = krb5_cc_get_principal(context, ccache, &princ);
97
if (ret && ret != KRB5_CC_NOTFOUND && ret != KRB5_FCC_NOFILE) {
98
com_err(argv[0], ret, _("getting principal from ccache"));
99
exit(1);
100
} else if (princ != NULL) {
101
ret = krb5_get_init_creds_opt_set_fast_ccache(context, opts, ccache);
102
if (ret) {
103
com_err(argv[0], ret, _("while setting FAST ccache"));
104
exit(1);
105
}
106
}
107
ret = krb5_cc_close(context, ccache);
108
if (ret) {
109
com_err(argv[0], ret, _("closing ccache"));
110
exit(1);
111
}
112
if (pname != NULL) {
113
krb5_free_principal(context, princ);
114
princ = NULL;
115
ret = krb5_parse_name(context, pname, &princ);
116
if (ret) {
117
com_err(argv[0], ret, _("parsing client name"));
118
exit(1);
119
}
120
}
121
if (princ == NULL)
122
get_name_from_passwd_file(argv[0], context, &princ);
123
124
krb5_get_init_creds_opt_set_tkt_life(opts, 5 * 60);
125
krb5_get_init_creds_opt_set_renew_life(opts, 0);
126
krb5_get_init_creds_opt_set_forwardable(opts, 0);
127
krb5_get_init_creds_opt_set_proxiable(opts, 0);
128
129
ret = krb5_get_init_creds_password(context, &creds, princ, NULL,
130
krb5_prompter_posix, NULL, 0,
131
"kadmin/changepw", opts);
132
if (ret) {
133
if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
134
com_err(argv[0], 0,
135
_("Password incorrect while getting initial ticket"));
136
} else {
137
com_err(argv[0], ret, _("getting initial ticket"));
138
}
139
140
krb5_get_init_creds_opt_free(context, opts);
141
exit(1);
142
}
143
144
pwlen = sizeof(pw);
145
ret = krb5_read_password(context, P1, P2, pw, &pwlen);
146
if (ret) {
147
com_err(argv[0], ret, _("while reading password"));
148
krb5_get_init_creds_opt_free(context, opts);
149
exit(1);
150
}
151
152
ret = krb5_change_password(context, &creds, pw, &result_code,
153
&result_code_string, &result_string);
154
if (ret) {
155
com_err(argv[0], ret, _("changing password"));
156
krb5_get_init_creds_opt_free(context, opts);
157
exit(1);
158
}
159
160
if (result_code) {
161
if (krb5_chpw_message(context, &result_string, &message) != 0)
162
message = NULL;
163
printf("%.*s%s%s\n",
164
(int)result_code_string.length, result_code_string.data,
165
message ? ": " : "", message ? message : NULL);
166
krb5_free_string(context, message);
167
krb5_get_init_creds_opt_free(context, opts);
168
exit(2);
169
}
170
171
free(result_string.data);
172
free(result_code_string.data);
173
krb5_get_init_creds_opt_free(context, opts);
174
175
printf(_("Password changed.\n"));
176
exit(0);
177
}
178
179