1 /* $OpenBSD: login_krb5.c,v 1.27 2013/06/21 13:35:26 ajacoutot Exp $ */
4 * Copyright (c) 2001, 2002 Hans Insulander <hin@openbsd.org>.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 krb5_syslog(krb5_context context
, int level
, krb5_error_code code
, char *fmt
, ...)
45 const char *s
= krb5_get_error_message(context
, code
);
48 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
50 syslog(level
, "%s: %s", buf
, s
);
51 krb5_free_error_message(context
, s
);
55 store_tickets(struct passwd
*pwd
, int ticket_newfiles
, int ticket_store
,
58 char cc_file
[PATH_MAX
];
59 krb5_ccache ccache_store
;
62 snprintf(cc_file
, sizeof(cc_file
), "FILE:/tmp/krb5cc_%d",
65 snprintf(cc_file
, sizeof(cc_file
), "%s",
66 krb5_cc_default_name(context
));
69 ret
= krb5_cc_resolve(context
, cc_file
, &ccache_store
);
71 krb5_syslog(context
, LOG_ERR
, ret
,
76 ret
= krb5_cc_copy_cache(context
, ccache
, ccache_store
);
78 krb5_syslog(context
, LOG_ERR
, ret
,
79 "krb5_cc_copy_cache");
81 chown(krb5_cc_get_name(context
, ccache_store
),
82 pwd
->pw_uid
, pwd
->pw_gid
);
84 fprintf(back
, BI_SETENV
" KRB5CCNAME %s:%s\n",
85 krb5_cc_get_type(context
, ccache_store
),
86 krb5_cc_get_name(context
, ccache_store
));
91 krb5_login(char *username
, char *invokinguser
, char *password
, int login
,
92 int tickets
, char *class)
95 int return_code
= AUTH_FAILED
;
98 if (username
== NULL
|| password
== NULL
)
101 if (strcmp(__progname
, "-krb5-or-pwd") == 0 &&
102 strcmp(username
,"root") == 0 && invokinguser
[0] == '\0')
103 return (AUTH_FAILED
);
105 lc
= login_getclass(class);
107 noverify
= login_getcapbool(lc
, "krb5-noverify", noverify
);
109 ret
= krb5_init_context(&context
);
111 krb5_syslog(context
, LOG_ERR
, ret
, "krb5_init_context");
115 ret
= krb5_cc_new_unique(context
, krb5_mcc_ops
.prefix
, NULL
, &ccache
);
117 krb5_syslog(context
, LOG_ERR
, ret
, "krb5_cc_new_unique");
121 if (strcmp(username
, "root") == 0 && invokinguser
[0] != '\0') {
124 ret
= asprintf(&tmp
, "%s/root", invokinguser
);
126 krb5_syslog(context
, LOG_ERR
, ret
, "asprintf");
129 ret
= krb5_parse_name(context
, tmp
, &princ
);
132 ret
= krb5_parse_name(context
, username
, &princ
);
134 krb5_syslog(context
, LOG_ERR
, ret
, "krb5_parse_name");
138 ret
= krb5_verify_user_lrealm(context
, princ
, ccache
,
139 password
, !noverify
, NULL
);
145 pwd
= getpwnam(username
);
147 krb5_syslog(context
, LOG_ERR
, ret
,
148 "%s: no such user", username
);
149 return (AUTH_FAILED
);
151 fprintf(back
, BI_AUTH
"\n");
152 store_tickets(pwd
, login
&& tickets
, login
&& tickets
, login
);
153 return_code
= AUTH_OK
;
156 case KRB5KRB_AP_ERR_MODIFIED
:
157 krb5_syslog(context
, LOG_ERR
, ret
, "KRB5KRB_AP_ERR_MODIFIED");
159 case KRB5KRB_AP_ERR_BAD_INTEGRITY
:
160 krb5_syslog(context
, LOG_ERR
, ret
, "KRB5KRB_AP_ERR_BAD_INTEGRITY");
163 krb5_syslog(context
, LOG_ERR
, ret
, "verify");
167 krb5_free_principal(context
, princ
);
168 krb5_cc_close(context
, ccache
);
169 krb5_free_context(context
);
171 return (return_code
);