~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/heimdal/kpasswd/kpasswd.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan
 
3
 * (Royal Institute of Technology, Stockholm, Sweden).
 
4
 * All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 *
 
10
 * 1. Redistributions of source code must retain the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer.
 
12
 *
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer in the
 
15
 *    documentation and/or other materials provided with the distribution.
 
16
 *
 
17
 * 3. Neither the name of the Institute nor the names of its contributors
 
18
 *    may be used to endorse or promote products derived from this software
 
19
 *    without specific prior written permission.
 
20
 *
 
21
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
31
 * SUCH DAMAGE.
 
32
 */
 
33
 
 
34
#include "kpasswd_locl.h"
 
35
RCSID("$Id$");
 
36
 
 
37
static int version_flag;
 
38
static int help_flag;
 
39
static char *admin_principal_str;
 
40
static char *cred_cache_str;
 
41
 
 
42
static struct getargs args[] = {
 
43
    { "admin-principal",        0,   arg_string, &admin_principal_str },
 
44
    { "cache",                  'c', arg_string, &cred_cache_str },
 
45
    { "version",                0,   arg_flag, &version_flag },
 
46
    { "help",                   0,   arg_flag, &help_flag }
 
47
};
 
48
 
 
49
static void
 
50
usage (int ret, struct getargs *a, int num_args)
 
51
{
 
52
    arg_printusage (a, num_args, NULL, "[principal ...]");
 
53
    exit (ret);
 
54
}
 
55
 
 
56
static int
 
57
change_password(krb5_context context,
 
58
                krb5_principal principal,
 
59
                krb5_ccache id)
 
60
{
 
61
    krb5_data result_code_string, result_string;
 
62
    int result_code;
 
63
    krb5_error_code ret;
 
64
    char pwbuf[BUFSIZ];
 
65
    char *msg, *name;
 
66
 
 
67
    krb5_data_zero (&result_code_string);
 
68
    krb5_data_zero (&result_string);
 
69
 
 
70
    name = msg = NULL;
 
71
    if (principal == NULL)
 
72
        asprintf(&msg, "New password: ");
 
73
    else {
 
74
        ret = krb5_unparse_name(context, principal, &name);
 
75
        if (ret)
 
76
            krb5_err(context, 1, ret, "krb5_unparse_name");
 
77
 
 
78
        asprintf(&msg, "New password for %s: ", name);
 
79
    }
 
80
 
 
81
    if (msg == NULL)
 
82
        krb5_errx (context, 1, "out of memory");
 
83
 
 
84
    ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), msg, 1);
 
85
    free(msg);
 
86
    if (name)
 
87
        free(name);
 
88
    if (ret != 0) {
 
89
        return 1;
 
90
    }
 
91
 
 
92
    ret = krb5_set_password_using_ccache (context, id, pwbuf,
 
93
                                          principal,
 
94
                                          &result_code,
 
95
                                          &result_code_string,
 
96
                                          &result_string);
 
97
    if (ret) {
 
98
        krb5_warn (context, ret, "krb5_set_password_using_ccache");
 
99
        return 1;
 
100
    }
 
101
 
 
102
    printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code),
 
103
            result_string.length > 0 ? " : " : "",
 
104
            (int)result_string.length,
 
105
            result_string.length > 0 ? (char *)result_string.data : "");
 
106
 
 
107
    krb5_data_free (&result_code_string);
 
108
    krb5_data_free (&result_string);
 
109
 
 
110
    return ret != 0;
 
111
}
 
112
 
 
113
 
 
114
int
 
115
main (int argc, char **argv)
 
116
{
 
117
    krb5_error_code ret;
 
118
    krb5_context context;
 
119
    krb5_principal principal;
 
120
    int optind = 0;
 
121
    krb5_get_init_creds_opt *opt;
 
122
    krb5_ccache id = NULL;
 
123
    int exit_value;
 
124
 
 
125
    optind = krb5_program_setup(&context, argc, argv,
 
126
                                args, sizeof(args) / sizeof(args[0]), usage);
 
127
 
 
128
    if (help_flag)
 
129
        usage (0, args, sizeof(args) / sizeof(args[0]));
 
130
 
 
131
    if(version_flag){
 
132
        print_version (NULL);
 
133
        exit(0);
 
134
    }
 
135
 
 
136
    argc -= optind;
 
137
    argv += optind;
 
138
 
 
139
    ret = krb5_init_context (&context);
 
140
    if (ret)
 
141
        errx (1, "krb5_init_context failed: %d", ret);
 
142
 
 
143
    ret = krb5_get_init_creds_opt_alloc (context, &opt);
 
144
    if (ret)
 
145
        krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
 
146
 
 
147
    krb5_get_init_creds_opt_set_tkt_life (opt, 300);
 
148
    krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
 
149
    krb5_get_init_creds_opt_set_proxiable (opt, FALSE);
 
150
 
 
151
    if (cred_cache_str) {
 
152
        ret = krb5_cc_resolve(context, cred_cache_str, &id);
 
153
        if (ret)
 
154
            krb5_err (context, 1, ret, "krb5_cc_resolve");
 
155
    } else {
 
156
        ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id);
 
157
        if (ret)
 
158
            krb5_err (context, 1, ret, "krb5_cc_gen_new");
 
159
    }
 
160
 
 
161
    if (cred_cache_str == NULL) {
 
162
        krb5_principal admin_principal = NULL;
 
163
        krb5_creds cred;
 
164
 
 
165
        if (admin_principal_str) {
 
166
            ret = krb5_parse_name (context, admin_principal_str,
 
167
                                   &admin_principal);
 
168
            if (ret)
 
169
                krb5_err (context, 1, ret, "krb5_parse_name");
 
170
        } else if (argc == 1) {
 
171
            ret = krb5_parse_name (context, argv[0], &admin_principal);
 
172
            if (ret)
 
173
                krb5_err (context, 1, ret, "krb5_parse_name");
 
174
        } else {
 
175
            ret = krb5_get_default_principal (context, &admin_principal);
 
176
            if (ret)
 
177
                krb5_err (context, 1, ret, "krb5_get_default_principal");
 
178
        }
 
179
 
 
180
        ret = krb5_get_init_creds_password (context,
 
181
                                            &cred,
 
182
                                            admin_principal,
 
183
                                            NULL,
 
184
                                            krb5_prompter_posix,
 
185
                                            NULL,
 
186
                                            0,
 
187
                                            "kadmin/changepw",
 
188
                                            opt);
 
189
        switch (ret) {
 
190
        case 0:
 
191
            break;
 
192
        case KRB5_LIBOS_PWDINTR :
 
193
            return 1;
 
194
        case KRB5KRB_AP_ERR_BAD_INTEGRITY :
 
195
        case KRB5KRB_AP_ERR_MODIFIED :
 
196
            krb5_errx(context, 1, "Password incorrect");
 
197
            break;
 
198
        default:
 
199
            krb5_err(context, 1, ret, "krb5_get_init_creds");
 
200
        }
 
201
        
 
202
        krb5_get_init_creds_opt_free(context, opt);
 
203
        
 
204
        ret = krb5_cc_initialize(context, id, admin_principal);
 
205
        krb5_free_principal(context, admin_principal);
 
206
        if (ret)
 
207
            krb5_err(context, 1, ret, "krb5_cc_initialize");
 
208
 
 
209
        ret = krb5_cc_store_cred(context, id, &cred);
 
210
        if (ret)
 
211
            krb5_err(context, 1, ret, "krb5_cc_store_cred");
 
212
        
 
213
        krb5_free_cred_contents (context, &cred);
 
214
    }
 
215
 
 
216
    if (argc == 0) {
 
217
        exit_value = change_password(context, NULL, id);
 
218
    } else {
 
219
        exit_value = 0;
 
220
 
 
221
        while (argc-- > 0) {
 
222
 
 
223
            ret = krb5_parse_name (context, argv[0], &principal);
 
224
            if (ret)
 
225
                krb5_err (context, 1, ret, "krb5_parse_name");
 
226
 
 
227
            ret = change_password(context, principal, id);
 
228
            if (ret)
 
229
                exit_value = 1;
 
230
            krb5_free_principal(context, principal);
 
231
            argv++;
 
232
        }
 
233
    }
 
234
 
 
235
    if (cred_cache_str == NULL) {
 
236
        ret = krb5_cc_destroy(context, id);
 
237
        if (ret)
 
238
            krb5_err (context, 1, ret, "krb5_cc_destroy");
 
239
    } else {
 
240
        ret = krb5_cc_close(context, id);
 
241
        if (ret)
 
242
            krb5_err (context, 1, ret, "krb5_cc_close");
 
243
    }
 
244
 
 
245
    krb5_free_context (context);
 
246
    return exit_value;
 
247
}