No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / appl / popper / pop_pass.c
blobdc87dd2b381c564e11a77033418e8886c40107a3
1 /*
2 * Copyright (c) 1989 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
7 #include <popper.h>
8 #ifdef HAVE_CRYPT_H
9 #include <crypt.h>
10 #endif
12 __RCSID("$Heimdal: pop_pass.c 19078 2006-11-20 18:12:41Z lha $"
13 "$NetBSD$");
15 #ifdef KRB4
16 static int
17 krb4_verify_password (POP *p)
19 int status;
20 char lrealm[REALM_SZ];
21 char tkt[MaxPathLen];
23 status = krb_get_lrealm(lrealm,1);
24 if (status == KFAILURE) {
25 pop_log(p, POP_PRIORITY, "%s: (%s.%s@%s) %s", p->client,
26 p->kdata.pname, p->kdata.pinst, p->kdata.prealm,
27 krb_get_err_text(status));
28 return 1;
30 snprintf(tkt, sizeof(tkt), "%s_popper.%u", TKT_ROOT, (unsigned)getpid());
31 krb_set_tkt_string (tkt);
33 status = krb_verify_user(p->user, "", lrealm,
34 p->pop_parm[1], KRB_VERIFY_SECURE, "pop");
35 dest_tkt(); /* no point in keeping the tickets */
36 return status;
38 #endif /* KRB4 */
40 #ifdef KRB5
41 static int
42 krb5_verify_password (POP *p)
44 krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
45 krb5_get_init_creds_opt *get_options;
46 krb5_verify_init_creds_opt verify_options;
47 krb5_error_code ret;
48 krb5_principal client, server;
49 krb5_creds creds;
51 ret = krb5_get_init_creds_opt_alloc (p->context, &get_options);
52 if (ret) {
53 pop_log(p, POP_PRIORITY, "krb5_get_init_creds_opt_init: %s",
54 krb5_get_err_text (p->context, ret));
55 return 1;
58 krb5_get_init_creds_opt_set_preauth_list (get_options,
59 pre_auth_types,
60 1);
62 krb5_verify_init_creds_opt_init (&verify_options);
64 ret = krb5_parse_name (p->context, p->user, &client);
65 if (ret) {
66 pop_log(p, POP_PRIORITY, "krb5_parse_name: %s",
67 krb5_get_err_text (p->context, ret));
68 return 1;
71 ret = krb5_get_init_creds_password (p->context,
72 &creds,
73 client,
74 p->pop_parm[1],
75 NULL,
76 NULL,
78 NULL,
79 get_options);
80 krb5_get_init_creds_opt_free(p->context, get_options);
81 if (ret) {
82 pop_log(p, POP_PRIORITY,
83 "krb5_get_init_creds_password: %s",
84 krb5_get_err_text (p->context, ret));
85 return 1;
88 ret = krb5_sname_to_principal (p->context,
89 p->myhost,
90 "pop",
91 KRB5_NT_SRV_HST,
92 &server);
93 if (ret) {
94 pop_log(p, POP_PRIORITY,
95 "krb5_get_init_creds_password: %s",
96 krb5_get_err_text (p->context, ret));
97 return 1;
100 ret = krb5_verify_init_creds (p->context,
101 &creds,
102 server,
103 NULL,
104 NULL,
105 &verify_options);
106 krb5_free_principal (p->context, client);
107 krb5_free_principal (p->context, server);
108 krb5_free_cred_contents (p->context, &creds);
109 return ret;
111 #endif
113 * pass: Obtain the user password from a POP client
117 login_user(POP *p)
119 struct stat st;
120 struct passwd *pw;
122 /* Look for the user in the password file */
123 if ((pw = k_getpwnam(p->user)) == NULL) {
124 pop_log(p, POP_PRIORITY, "user %s (from %s) not found",
125 p->user, p->ipaddr);
126 return pop_msg(p, POP_FAILURE, "Login incorrect.");
129 pop_log(p, POP_INFO, "login from %s as %s", p->ipaddr, p->user);
131 /* Build the name of the user's maildrop */
132 snprintf(p->drop_name, sizeof(p->drop_name), "%s/%s", POP_MAILDIR, p->user);
133 if(stat(p->drop_name, &st) < 0 || !S_ISDIR(st.st_mode)){
134 /* Make a temporary copy of the user's maildrop */
135 /* and set the group and user id */
136 if (pop_dropcopy(p, pw) != POP_SUCCESS) return (POP_FAILURE);
138 /* Get information about the maildrop */
139 if (pop_dropinfo(p) != POP_SUCCESS) return(POP_FAILURE);
140 } else {
141 if(changeuser(p, pw) != POP_SUCCESS) return POP_FAILURE;
142 if(pop_maildir_info(p) != POP_SUCCESS) return POP_FAILURE;
144 /* Initialize the last-message-accessed number */
145 p->last_msg = 0;
146 return POP_SUCCESS;
150 pop_pass (POP *p)
152 struct passwd *pw;
153 int i;
154 int status;
156 /* Make one string of all these parameters */
158 for (i = 1; i < p->parm_count; ++i)
159 p->pop_parm[i][strlen(p->pop_parm[i])] = ' ';
161 /* Look for the user in the password file */
162 if ((pw = k_getpwnam(p->user)) == NULL)
163 return (pop_msg(p,POP_FAILURE,
164 "Password supplied for \"%s\" is incorrect.",
165 p->user));
167 if (p->kerberosp) {
168 #ifdef KRB4
169 if (p->version == 4) {
170 if(kuserok (&p->kdata, p->user)) {
171 pop_log(p, POP_PRIORITY,
172 "%s: (%s.%s@%s) tried to retrieve mail for %s.",
173 p->client, p->kdata.pname, p->kdata.pinst,
174 p->kdata.prealm, p->user);
175 return(pop_msg(p,POP_FAILURE,
176 "Popping not authorized"));
178 pop_log(p, POP_INFO, "%s: %s.%s@%s -> %s",
179 p->ipaddr,
180 p->kdata.pname, p->kdata.pinst, p->kdata.prealm,
181 p->user);
182 } else
183 #endif /* KRB4 */
184 #ifdef KRB5
185 if (p->version == 5) {
186 char *name;
188 if (!krb5_kuserok (p->context, p->principal, p->user)) {
189 pop_log (p, POP_PRIORITY,
190 "krb5 permission denied");
191 return pop_msg(p, POP_FAILURE,
192 "Popping not authorized");
194 if(krb5_unparse_name (p->context, p->principal, &name) == 0) {
195 pop_log(p, POP_INFO, "%s: %s -> %s",
196 p->ipaddr, name, p->user);
197 free (name);
199 } else {
200 pop_log (p, POP_PRIORITY, "kerberos authentication failed");
201 return pop_msg (p, POP_FAILURE,
202 "kerberos authentication failed");
204 #endif
206 } else {
207 /* We don't accept connections from users with null passwords */
208 if (pw->pw_passwd == NULL)
209 return (pop_msg(p,
210 POP_FAILURE,
211 "Password supplied for \"%s\" is incorrect.",
212 p->user));
214 #ifdef OTP
215 if (otp_verify_user (&p->otp_ctx, p->pop_parm[1]) == 0)
216 /* pass OK */;
217 else
218 #endif
219 /* Compare the supplied password with the password file entry */
220 if (p->auth_level != AUTH_NONE)
221 return pop_msg(p, POP_FAILURE,
222 "Password supplied for \"%s\" is incorrect.",
223 p->user);
224 else if (!strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd))
225 /* pass OK */;
226 else {
227 int ret = -1;
228 #ifdef KRB4
229 ret = krb4_verify_password (p);
230 #endif
231 #ifdef KRB5
232 if(ret)
233 ret = krb5_verify_password (p);
234 #endif
235 if(ret)
236 return pop_msg(p, POP_FAILURE,
237 "Password incorrect");
240 status = login_user(p);
241 if(status != POP_SUCCESS)
242 return status;
244 /* Authorization completed successfully */
245 return (pop_msg (p, POP_SUCCESS,
246 "%s has %d message(s) (%ld octets).",
247 p->user, p->msg_count, p->drop_size));