15331Samw /*
25331Samw * CDDL HEADER START
35331Samw *
45331Samw * The contents of this file are subject to the terms of the
55331Samw * Common Development and Distribution License (the "License").
65331Samw * You may not use this file except in compliance with the License.
75331Samw *
85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw * or http://www.opensolaris.org/os/licensing.
105331Samw * See the License for the specific language governing permissions
115331Samw * and limitations under the License.
125331Samw *
135331Samw * When distributing Covered Code, include this CDDL HEADER in each
145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw * If applicable, add the following below this CDDL HEADER, with the
165331Samw * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw *
195331Samw * CDDL HEADER END
205331Samw */
2111411SSurya.Prakki@Sun.COM
225331Samw /*
23*12508Samw@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
245331Samw */
255331Samw /*
265331Samw * Copyright 1990 by the Massachusetts Institute of Technology.
275331Samw * All Rights Reserved.
285331Samw *
295331Samw * Export of this software from the United States of America may
305331Samw * require a specific license from the United States Government.
315331Samw * It is the responsibility of any person or organization contemplating
325331Samw * export to obtain such a license before exporting.
335331Samw *
345331Samw * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
355331Samw * distribute this software and its documentation for any purpose and
365331Samw * without fee is hereby granted, provided that the above copyright
375331Samw * notice appear in all copies and that both that copyright notice and
385331Samw * this permission notice appear in supporting documentation, and that
395331Samw * the name of M.I.T. not be used in advertising or publicity pertaining
405331Samw * to distribution of the software without specific, written prior
415331Samw * permission. Furthermore if you modify this software you must label
425331Samw * your software as modified software and not distribute it in such a
435331Samw * fashion that it might be confused with the original M.I.T. software.
445331Samw * M.I.T. makes no representations about the suitability of
455331Samw * this software for any purpose. It is provided "as is" without express
465331Samw * or implied warranty.
475331Samw *
485331Samw *
495331Samw * Initialize a credentials cache.
505331Samw */
515331Samw #include <kerberosv5/krb5.h>
525331Samw #include <kerberosv5/com_err.h>
535521Sas200622 #include <assert.h>
545331Samw #include <stdio.h>
555331Samw #include <syslog.h>
566139Sjb150015 #include <errno.h>
575331Samw
585331Samw #include <smbsrv/libsmbns.h>
595331Samw #include <smbns_krb.h>
605331Samw
6110717Samw@Sun.COM int
smb_kinit(char * principal_name,char * principal_passwd)6210717Samw@Sun.COM smb_kinit(char *principal_name, char *principal_passwd)
635331Samw {
6410717Samw@Sun.COM krb5_context ctx = NULL;
6510717Samw@Sun.COM krb5_ccache cc = NULL;
6610717Samw@Sun.COM krb5_principal me = NULL;
6710717Samw@Sun.COM krb5_creds my_creds;
6810717Samw@Sun.COM krb5_error_code code;
6910717Samw@Sun.COM const char *errmsg = NULL;
7010717Samw@Sun.COM const char *doing = NULL;
715331Samw
7210717Samw@Sun.COM assert(principal_name != NULL);
7310717Samw@Sun.COM assert(principal_passwd != NULL);
745331Samw
755331Samw (void) memset(&my_creds, 0, sizeof (my_creds));
765331Samw
775331Samw /*
7810717Samw@Sun.COM * From this point on, we can goto cleanup because the key variables
7910717Samw@Sun.COM * are initialized.
805331Samw */
815331Samw
8210717Samw@Sun.COM code = krb5_init_context(&ctx);
835331Samw if (code) {
84*12508Samw@Sun.COM doing = "smbns_krb: initializing context";
855331Samw goto cleanup;
865331Samw }
875331Samw
8810717Samw@Sun.COM code = krb5_cc_default(ctx, &cc);
8910717Samw@Sun.COM if (code != 0) {
90*12508Samw@Sun.COM doing = "smbns_krb: resolve default credentials cache";
915331Samw goto cleanup;
925331Samw }
935331Samw
9410717Samw@Sun.COM /* Use specified name */
9510717Samw@Sun.COM code = krb5_parse_name(ctx, principal_name, &me);
9610717Samw@Sun.COM if (code != 0) {
97*12508Samw@Sun.COM doing = "smbns_krb: parsing principal name";
985331Samw goto cleanup;
995331Samw }
1005331Samw
10110717Samw@Sun.COM code = krb5_get_init_creds_password(ctx, &my_creds, me,
10210717Samw@Sun.COM principal_passwd, NULL, 0, (krb5_deltat)0,
10310717Samw@Sun.COM NULL, NULL);
10410717Samw@Sun.COM if (code != 0) {
105*12508Samw@Sun.COM doing = "smbns_krb: getting initial credentials";
1065331Samw
10710717Samw@Sun.COM if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
108*12508Samw@Sun.COM errmsg = "smbns_krb: Password incorrect";
10910717Samw@Sun.COM }
1105521Sas200622
11110717Samw@Sun.COM goto cleanup;
11210717Samw@Sun.COM }
1135331Samw
11410717Samw@Sun.COM code = krb5_cc_initialize(ctx, cc, me);
11510717Samw@Sun.COM if (code != 0) {
116*12508Samw@Sun.COM doing = "smbns_krb: initializing cache";
11710717Samw@Sun.COM goto cleanup;
1185331Samw }
1195331Samw
12010717Samw@Sun.COM code = krb5_cc_store_cred(ctx, cc, &my_creds);
12110717Samw@Sun.COM if (code != 0) {
122*12508Samw@Sun.COM doing = "smbns_krb: storing credentials";
12310717Samw@Sun.COM goto cleanup;
1245331Samw }
1255331Samw
12610717Samw@Sun.COM /* SUCCESS! */
1275331Samw
12810717Samw@Sun.COM cleanup:
12910717Samw@Sun.COM if (code != 0) {
13010717Samw@Sun.COM if (errmsg == NULL)
131*12508Samw@Sun.COM smb_krb5_log_errmsg(ctx, doing, code);
132*12508Samw@Sun.COM else
133*12508Samw@Sun.COM syslog(LOG_ERR, "%s (%s)", doing, errmsg);
1345331Samw }
1355521Sas200622
13610717Samw@Sun.COM if (my_creds.client == me) {
13710717Samw@Sun.COM my_creds.client = NULL;
13810717Samw@Sun.COM }
13910717Samw@Sun.COM krb5_free_cred_contents(ctx, &my_creds);
1405331Samw
14110717Samw@Sun.COM if (me)
14210717Samw@Sun.COM krb5_free_principal(ctx, me);
14310717Samw@Sun.COM if (cc)
14411411SSurya.Prakki@Sun.COM (void) krb5_cc_close(ctx, cc);
14510717Samw@Sun.COM if (ctx)
14610717Samw@Sun.COM krb5_free_context(ctx);
1475331Samw
14810717Samw@Sun.COM return (code == 0);
1495331Samw }
1506139Sjb150015
1516139Sjb150015 /*
152*12508Samw@Sun.COM * Invoke krb5_get_error_message() to generate a richer error message.
153*12508Samw@Sun.COM */
154*12508Samw@Sun.COM void
smb_krb5_log_errmsg(krb5_context ctx,const char * prefix,krb5_error_code code)155*12508Samw@Sun.COM smb_krb5_log_errmsg(krb5_context ctx, const char *prefix, krb5_error_code code)
156*12508Samw@Sun.COM {
157*12508Samw@Sun.COM const char *msg;
158*12508Samw@Sun.COM
159*12508Samw@Sun.COM msg = krb5_get_error_message(ctx, code);
160*12508Samw@Sun.COM syslog(LOG_ERR, "%s (%s)", prefix, msg);
161*12508Samw@Sun.COM krb5_free_error_message(ctx, msg);
162*12508Samw@Sun.COM }
163*12508Samw@Sun.COM
164*12508Samw@Sun.COM /*
1656139Sjb150015 * smb_ccache_init
1666139Sjb150015 *
1676139Sjb150015 * Creates the directory where the Kerberos ccache file is located
1686139Sjb150015 * and set KRB5CCNAME in the environment.
1696139Sjb150015 *
1706139Sjb150015 * Returns 0 upon succcess. Otherwise, returns
1716139Sjb150015 * -1 if it fails to create the specified directory fails.
1726139Sjb150015 * -2 if it fails to set the KRB5CCNAME environment variable.
1736139Sjb150015 */
1746139Sjb150015 int
smb_ccache_init(char * dir,char * filename)1756139Sjb150015 smb_ccache_init(char *dir, char *filename)
1766139Sjb150015 {
1776139Sjb150015 static char buf[MAXPATHLEN];
1786139Sjb150015
1796139Sjb150015 if ((mkdir(dir, 0700) < 0) && (errno != EEXIST))
1806139Sjb150015 return (-1);
1816139Sjb150015
1826139Sjb150015 (void) snprintf(buf, MAXPATHLEN, "KRB5CCNAME=%s/%s", dir, filename);
1836139Sjb150015 if (putenv(buf) != 0)
1846139Sjb150015 return (-2);
1856139Sjb150015 return (0);
1866139Sjb150015 }
1876139Sjb150015
1886139Sjb150015 void
smb_ccache_remove(char * path)1896139Sjb150015 smb_ccache_remove(char *path)
1906139Sjb150015 {
1916139Sjb150015 if ((remove(path) < 0) && (errno != ENOENT))
192*12508Samw@Sun.COM syslog(LOG_ERR, "smbns_krb: failed to remove ccache (%s)",
193*12508Samw@Sun.COM path);
1946139Sjb150015 }
195