Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / kadmin / kpasswd_standalone.c
1 /*
2  * Copyright 1988 by the Massachusetts Institute of Technology.
3  *
4  * For copying and distribution information, please see the file
5  * Copyright.MIT.
6  *
7  * change your password with kerberos
8  */
9
10 #ifndef lint
11 #if 0
12 static char rcsid_kpasswd_c[] =
13     "BonesHeader: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/kpasswd.c,v 4.3 89/09/26 09:33:02 jtkohl Exp ";
14 #endif
15 static const char rcsid[] =
16  "$FreeBSD: src/crypto/kerberosIV/kadmin/kpasswd_standalone.c,v 1.1.8.3 2003/02/14 22:37:37 nectar Exp $";
17 #endif  lint
18
19 /*
20  * kpasswd
21  * change your password with kerberos
22  */
23
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <sys/param.h>
27 #include <netinet/in.h>
28 #include <com_err.h>
29 #include <err.h>
30 #include <krb.h>
31 #include <string.h>
32 #include <pwd.h>
33 #include <unistd.h>
34 #include "kadm.h"
35
36 #include "extern.h"
37
38 extern void krb_set_tkt_string();
39 static void go_home(char *, int);
40
41
42 int krb_passwd(char *uname, char *iflag, char *rflag, char *uflag)
43 {
44     char name[ANAME_SZ];        /* name of user */
45     char inst[INST_SZ];         /* instance of user */
46     char realm[REALM_SZ];       /* realm of user */
47     char default_name[ANAME_SZ];
48     char default_inst[INST_SZ];
49     char default_realm[REALM_SZ];
50     int realm_given = 0;        /* True if realm was give on cmdline */
51     int use_default = 1;        /* True if we should use default name */
52     struct passwd *pw;
53     int status;                 /* return code */
54     des_cblock new_key;
55     extern char *optarg;
56     extern int optind;
57     char tktstring[MAXPATHLEN];
58
59     void get_pw_new_key();
60
61 #ifdef NOENCRYPTION
62 int placebo_long_pw_string();
63 #define read_long_pw_string placebo_read_pw_string
64 #else
65 #define read_long_pw_string des_read_pw_string
66 #endif
67
68     bzero(name, sizeof(name));
69     bzero(inst, sizeof(inst));
70     bzero(realm, sizeof(realm));
71
72     if (krb_get_tf_fullname(TKT_FILE, default_name, default_inst,
73                             default_realm) != KSUCCESS) {
74         pw = getpwuid((int) getuid());
75         if (pw) {
76                 strcpy(default_name, pw->pw_name);
77         } else {
78             /* seems like a null name is kinda silly */
79                 strcpy(default_name, "");
80         }
81         strcpy(default_inst, "");
82         if (krb_get_lrealm(default_realm, 1) != KSUCCESS)
83             strcpy(default_realm, KRB_REALM);
84     }
85
86     if(uflag) {
87             if ((status = kname_parse(name, inst, realm, uflag))) {
88                     errx(2, "Kerberos error: %s", krb_err_txt[status]);
89             }
90             if (realm[0])
91                 realm_given++;
92             else
93                 if (krb_get_lrealm(realm, 1) != KSUCCESS)
94                     strcpy(realm, KRB_REALM);
95     }
96
97     if(uname) {
98             if (k_isname(uname)) {
99                     strncpy(name, uname, sizeof(name) - 1);
100             } else {
101                     errx(1, "bad name: %s", uname);
102             }
103     }
104
105     if(iflag) {
106             if (k_isinst(iflag)) {
107                     strncpy(inst, iflag, sizeof(inst) - 1);
108             } else {
109                     errx(1, "bad instance: %s", iflag);
110             }
111     }
112
113     if(rflag) {
114             if (k_isrealm(rflag)) {
115                     strncpy(realm, rflag, sizeof(realm) - 1);
116                     realm_given++;
117             } else {
118                     errx(1, "bad realm: %s", rflag);
119             }
120     }
121
122     if(uname || iflag || rflag || uflag) use_default = 0;
123
124     if (use_default) {
125         strcpy(name, default_name);
126         strcpy(inst, default_inst);
127         strcpy(realm, default_realm);
128     } else {
129         if (!name[0])
130             strcpy(name, default_name);
131         if (!realm[0])
132             strcpy(realm, default_realm);
133     }
134
135     (void) sprintf(tktstring, "/tmp/tkt_cpw_%d",getpid());
136     krb_set_tkt_string(tktstring);
137
138     get_pw_new_key(new_key, name, inst, realm, realm_given);
139
140     if ((status = kadm_init_link("changepw", KRB_MASTER, realm))
141         != KADM_SUCCESS)
142         com_err("kpasswd", status, "while initializing");
143     else if ((status = kadm_change_pw(new_key)) != KADM_SUCCESS)
144         com_err("kpasswd", status, " attempting to change password.");
145
146     if (status != KADM_SUCCESS)
147         fprintf(stderr,"Password NOT changed.\n");
148     else
149         printf("Password changed.\n");
150
151     (void) dest_tkt();
152     if (status)
153         exit(2);
154     else
155         exit(0);
156 }
157
158 void get_pw_new_key(new_key, name, inst, realm, print_realm)
159   des_cblock new_key;
160   char *name;
161   char *inst;
162   char *realm;
163   int print_realm;              /* True if realm was give on cmdline */
164 {
165     char ppromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
166     char pword[MAX_KPW_LEN];                   /* storage for the password */
167     char npromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
168
169     char local_realm[REALM_SZ];
170     int status;
171
172     /*
173      * We don't care about failure; this is to determine whether or
174      * not to print the realm in the prompt for a new password.
175      */
176     (void) krb_get_lrealm(local_realm, 1);
177
178     if (strcmp(local_realm, realm))
179         print_realm++;
180
181     (void) sprintf(ppromp,"Old password for %s%s%s%s%s:",
182                    name, *inst ? "." : "", inst,
183                    print_realm ? "@" : "", print_realm ? realm : "");
184     if (read_long_pw_string(pword, sizeof(pword)-1, ppromp, 0)) {
185         fprintf(stderr, "Error reading old password.\n");
186         exit(1);
187     }
188
189     if ((status = krb_get_pw_in_tkt(name, inst, realm, PWSERV_NAME,
190                                     KADM_SINST, 1, pword)) != KSUCCESS) {
191         if (status == INTK_BADPW) {
192             printf("Incorrect old password.\n");
193             exit(0);
194         }
195         else {
196             fprintf(stderr, "Kerberos error: %s\n", krb_err_txt[status]);
197             exit(1);
198         }
199     }
200     bzero(pword, sizeof(pword));
201     do {
202         (void) sprintf(npromp,"New Password for %s%s%s%s%s:",
203                        name, *inst ? "." : "", inst,
204                        print_realm ? "@" : "", print_realm ? realm : "");
205         if (read_long_pw_string(pword, sizeof(pword)-1, npromp, 1))
206             go_home("Error reading new password, password unchanged.\n",0);
207         if (strlen(pword) == 0)
208             printf("Null passwords are not allowed; try again.\n");
209     } while (strlen(pword) == 0);
210
211 #ifdef NOENCRYPTION
212     bzero((char *) new_key, sizeof(des_cblock));
213     new_key[0] = (unsigned char) 1;
214 #else
215     (void) des_string_to_key(pword, (des_cblock *)new_key);
216 #endif
217     bzero(pword, sizeof(pword));
218 }
219
220 static void
221 go_home(str,x)
222   char *str;
223   int x;
224 {
225     fprintf(stderr, str, x);
226     (void) dest_tkt();
227     exit(1);
228 }