17c478bd9Sstevel@tonic-gate /*
2159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
4*48bbca81SDaniel Hoffman * Copyright (c) 2016 by Delphix. All rights reserved.
57c478bd9Sstevel@tonic-gate */
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate
87c478bd9Sstevel@tonic-gate /*
97c478bd9Sstevel@tonic-gate * lib/krb5/os/kuserok.c
107c478bd9Sstevel@tonic-gate *
117c478bd9Sstevel@tonic-gate * Copyright 1990,1993 by the Massachusetts Institute of Technology.
127c478bd9Sstevel@tonic-gate * All Rights Reserved.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
157c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
167c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
177c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
18*48bbca81SDaniel Hoffman *
197c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
207c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
217c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
227c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
237c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
247c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
257c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
26159d09a2SMark Phalan * permission. Furthermore if you modify this software you must label
27159d09a2SMark Phalan * your software as modified software and not distribute it in such a
28159d09a2SMark Phalan * fashion that it might be confused with the original M.I.T. software.
29159d09a2SMark Phalan * M.I.T. makes no representations about the suitability of
307c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
317c478bd9Sstevel@tonic-gate * or implied warranty.
32*48bbca81SDaniel Hoffman *
337c478bd9Sstevel@tonic-gate *
347c478bd9Sstevel@tonic-gate * krb5_kuserok()
357c478bd9Sstevel@tonic-gate */
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate #include "k5-int.h"
38159d09a2SMark Phalan #if !defined(_WIN32) /* Not yet for Windows */
397c478bd9Sstevel@tonic-gate #include <stdio.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate #include <stdlib.h>
427c478bd9Sstevel@tonic-gate #include <pwd.h>
437c478bd9Sstevel@tonic-gate #include <libintl.h>
447c478bd9Sstevel@tonic-gate #include <gssapi/gssapi.h>
457c478bd9Sstevel@tonic-gate #include <gssapi/gssapi_ext.h>
467c478bd9Sstevel@tonic-gate #include <gssapi_krb5.h>
477c478bd9Sstevel@tonic-gate #include <gssapiP_krb5.h>
487c478bd9Sstevel@tonic-gate #include <syslog.h>
497c478bd9Sstevel@tonic-gate
50159d09a2SMark Phalan #if defined(_AIX) && defined(_IBMR2)
51159d09a2SMark Phalan #include <sys/access.h>
52159d09a2SMark Phalan /* xlc has a bug with "const" */
53159d09a2SMark Phalan #define getpwnam(user) getpwnam((char *)user)
54159d09a2SMark Phalan #endif
55159d09a2SMark Phalan
56159d09a2SMark Phalan #define MAX_USERNAME 65
57159d09a2SMark Phalan #define CACHE_FILENAME_LEN 35
58159d09a2SMark Phalan
59159d09a2SMark Phalan #if defined(__APPLE__) && defined(__MACH__)
60159d09a2SMark Phalan #include <hfs/hfs_mount.h> /* XXX */
61159d09a2SMark Phalan #define FILE_OWNER_OK(UID) ((UID) == 0 || (UID) == UNKNOWNUID)
62159d09a2SMark Phalan #else
63159d09a2SMark Phalan #define FILE_OWNER_OK(UID) ((UID) == 0)
64159d09a2SMark Phalan #endif
65159d09a2SMark Phalan
66159d09a2SMark Phalan /* Solaris Kerberos */
677c478bd9Sstevel@tonic-gate extern void
687c478bd9Sstevel@tonic-gate gsscred_set_options();
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate extern OM_uint32
717c478bd9Sstevel@tonic-gate gsscred_name_to_unix_cred_ext();
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate extern int
747c478bd9Sstevel@tonic-gate safechown(const char *src, uid_t uid, gid_t gid, int mode);
757c478bd9Sstevel@tonic-gate
76505d05c7Sgtb extern const char *error_message(long);
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate krb5_data tgtname = {
807c478bd9Sstevel@tonic-gate 0,
817c478bd9Sstevel@tonic-gate KRB5_TGS_NAME_SIZE,
827c478bd9Sstevel@tonic-gate KRB5_TGS_NAME
837c478bd9Sstevel@tonic-gate };
847c478bd9Sstevel@tonic-gate
85159d09a2SMark Phalan /* Solaris Kerberos */
867c478bd9Sstevel@tonic-gate static krb5_error_code
krb5_move_ccache(krb5_context kcontext,krb5_principal client,struct passwd * pwd)877c478bd9Sstevel@tonic-gate krb5_move_ccache(krb5_context kcontext, krb5_principal client,
887c478bd9Sstevel@tonic-gate struct passwd *pwd)
897c478bd9Sstevel@tonic-gate {
907c478bd9Sstevel@tonic-gate char *name = 0;
917c478bd9Sstevel@tonic-gate static char ccache_name_buf[CACHE_FILENAME_LEN];
927c478bd9Sstevel@tonic-gate krb5_ccache ccache = NULL;
937c478bd9Sstevel@tonic-gate krb5_error_code retval;
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate name = getenv(KRB5_ENV_CCNAME);
967c478bd9Sstevel@tonic-gate if (name == 0)
977c478bd9Sstevel@tonic-gate /*
987c478bd9Sstevel@tonic-gate * This means that there was no forwarding
997c478bd9Sstevel@tonic-gate * of creds
1007c478bd9Sstevel@tonic-gate */
1017c478bd9Sstevel@tonic-gate return (0);
1027c478bd9Sstevel@tonic-gate else {
1037c478bd9Sstevel@tonic-gate /*
1047c478bd9Sstevel@tonic-gate * creds have been forwarded and stored in
1057c478bd9Sstevel@tonic-gate * KRB5_ENV_CCNAME and now we need to store it
1067c478bd9Sstevel@tonic-gate * under uid
1077c478bd9Sstevel@tonic-gate */
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate krb5_creds mcreds, save_v5creds;
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate memset(&mcreds, 0, sizeof (mcreds));
1127c478bd9Sstevel@tonic-gate memset(&save_v5creds, 0, sizeof (save_v5creds));
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate mcreds.client = client;
1157c478bd9Sstevel@tonic-gate retval = krb5_build_principal_ext(kcontext, &mcreds.server,
1167c478bd9Sstevel@tonic-gate krb5_princ_realm(kcontext, client)->length,
1177c478bd9Sstevel@tonic-gate krb5_princ_realm(kcontext, client)->data,
1187c478bd9Sstevel@tonic-gate tgtname.length, tgtname.data,
1197c478bd9Sstevel@tonic-gate krb5_princ_realm(kcontext, client)->length,
1207c478bd9Sstevel@tonic-gate krb5_princ_realm(kcontext, client)->data,
1217c478bd9Sstevel@tonic-gate 0);
1227c478bd9Sstevel@tonic-gate if (retval) {
1237c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1247c478bd9Sstevel@tonic-gate gettext("KRB5: %s while creating"
1257c478bd9Sstevel@tonic-gate "V5 krbtgt principal "),
1267c478bd9Sstevel@tonic-gate error_message(retval));
1277c478bd9Sstevel@tonic-gate return (retval);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate mcreds.ticket_flags = 0;
1317c478bd9Sstevel@tonic-gate retval = krb5_cc_default(kcontext, &ccache);
1327c478bd9Sstevel@tonic-gate if (retval) {
1337c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1347c478bd9Sstevel@tonic-gate gettext("KRB5: %s while getting "
1357c478bd9Sstevel@tonic-gate "default cache "),
1367c478bd9Sstevel@tonic-gate error_message(retval));
1377c478bd9Sstevel@tonic-gate return (retval);
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate retval = krb5_cc_retrieve_cred(kcontext, ccache,
1417c478bd9Sstevel@tonic-gate 0,
1427c478bd9Sstevel@tonic-gate &mcreds, &save_v5creds);
1437c478bd9Sstevel@tonic-gate if (retval) {
1447c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1457c478bd9Sstevel@tonic-gate gettext("KRB5: %s while retrieving "
1467c478bd9Sstevel@tonic-gate "cerdentials "),
1477c478bd9Sstevel@tonic-gate error_message(retval));
1487c478bd9Sstevel@tonic-gate return (retval);
1497c478bd9Sstevel@tonic-gate }
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate * reset the env variable and recreate the
1527c478bd9Sstevel@tonic-gate * cache using the default cache name
1537c478bd9Sstevel@tonic-gate */
1547c478bd9Sstevel@tonic-gate retval = krb5_cc_destroy(kcontext, ccache);
1557c478bd9Sstevel@tonic-gate if (retval) {
1567c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1577c478bd9Sstevel@tonic-gate gettext("KRB5: %s while destroying cache "),
1587c478bd9Sstevel@tonic-gate error_message(retval));
1597c478bd9Sstevel@tonic-gate return (retval);
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate krb5_unsetenv(KRB5_ENV_CCNAME);
1627c478bd9Sstevel@tonic-gate snprintf(ccache_name_buf,
1637c478bd9Sstevel@tonic-gate CACHE_FILENAME_LEN,
1647c478bd9Sstevel@tonic-gate "FILE:/tmp/krb5cc_%d", pwd->pw_uid);
1657c478bd9Sstevel@tonic-gate krb5_setenv(KRB5_ENV_CCNAME, ccache_name_buf, 1);
1667c478bd9Sstevel@tonic-gate retval = krb5_cc_resolve(kcontext, ccache_name_buf, &ccache);
1677c478bd9Sstevel@tonic-gate if (retval) {
1687c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1697c478bd9Sstevel@tonic-gate gettext("KRB5: %s while resolving cache "),
1707c478bd9Sstevel@tonic-gate error_message(retval));
1717c478bd9Sstevel@tonic-gate return (retval);
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate retval = krb5_cc_initialize(kcontext, ccache, client);
1747c478bd9Sstevel@tonic-gate if (retval) {
1757c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1767c478bd9Sstevel@tonic-gate gettext("KRB5: %s while initializing cache "),
1777c478bd9Sstevel@tonic-gate error_message(retval));
1787c478bd9Sstevel@tonic-gate return (retval);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate retval = krb5_cc_store_cred(kcontext, ccache, &save_v5creds);
1817c478bd9Sstevel@tonic-gate if (retval) {
1827c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1837c478bd9Sstevel@tonic-gate gettext("KRB5: %s while storing creds "),
1847c478bd9Sstevel@tonic-gate error_message(retval));
1857c478bd9Sstevel@tonic-gate return (retval);
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate snprintf(ccache_name_buf,
1887c478bd9Sstevel@tonic-gate CACHE_FILENAME_LEN,
1897c478bd9Sstevel@tonic-gate "/tmp/krb5cc_%d", pwd->pw_uid);
1907c478bd9Sstevel@tonic-gate if (safechown(ccache_name_buf, pwd->pw_uid,
1917c478bd9Sstevel@tonic-gate pwd->pw_gid, -1) == -1) {
1927c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1937c478bd9Sstevel@tonic-gate gettext("KRB5: Can not change "
1947c478bd9Sstevel@tonic-gate "ownership of cache file, "
1957c478bd9Sstevel@tonic-gate "possible security breach\n"));
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate return (0);
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate /*
204159d09a2SMark Phalan * Solaris Kerberos:
2057c478bd9Sstevel@tonic-gate * krb5_gsscred: Given a kerberos principal try to find the corresponding
2067c478bd9Sstevel@tonic-gate * local uid via the gss cred table. Return TRUE if the uid was found in the
2077c478bd9Sstevel@tonic-gate * cred table, otherwise return FALSE.
2087c478bd9Sstevel@tonic-gate */
2097c478bd9Sstevel@tonic-gate static krb5_boolean
krb5_gsscred(krb5_principal principal,uid_t * uid)2107c478bd9Sstevel@tonic-gate krb5_gsscred(krb5_principal principal, uid_t *uid)
2117c478bd9Sstevel@tonic-gate {
2127c478bd9Sstevel@tonic-gate OM_uint32 minor, major;
2137c478bd9Sstevel@tonic-gate gss_name_t name;
2147c478bd9Sstevel@tonic-gate gss_buffer_desc name_buf;
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate name_buf.value = &principal;
2177c478bd9Sstevel@tonic-gate name_buf.length = sizeof (principal);
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate /*
2207c478bd9Sstevel@tonic-gate * Convert the kerb principal in to a gss name
2217c478bd9Sstevel@tonic-gate */
2227c478bd9Sstevel@tonic-gate major = gss_import_name(&minor, &name_buf,
2237c478bd9Sstevel@tonic-gate (gss_OID)gss_nt_krb5_principal, &name);
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate if (major != GSS_S_COMPLETE)
2267c478bd9Sstevel@tonic-gate return (FALSE);
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate gsscred_set_options();
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate /*
2317c478bd9Sstevel@tonic-gate * Get the uid mapping from the gsscred table.
2327c478bd9Sstevel@tonic-gate * (but set flag to not call back into this mech as we do krb5
2337c478bd9Sstevel@tonic-gate * auth_to_local name mapping from this module).
2347c478bd9Sstevel@tonic-gate */
2357c478bd9Sstevel@tonic-gate major = gsscred_name_to_unix_cred_ext(name, (gss_OID)gss_mech_krb5,
2367c478bd9Sstevel@tonic-gate uid, 0, 0, 0, 0);
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate (void) gss_release_name(&minor, &name);
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate if (major != GSS_S_COMPLETE)
2417c478bd9Sstevel@tonic-gate return (FALSE);
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate return (TRUE);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate /*
2477c478bd9Sstevel@tonic-gate * Given a Kerberos principal "principal", and a local username "luser",
2487c478bd9Sstevel@tonic-gate * determine whether user is authorized to login according to the
2497c478bd9Sstevel@tonic-gate * authorization file ("~luser/.k5login" by default). Returns TRUE
2507c478bd9Sstevel@tonic-gate * if authorized, FALSE if not authorized.
2517c478bd9Sstevel@tonic-gate *
2527c478bd9Sstevel@tonic-gate * If there is no account for "luser" on the local machine, returns
2537c478bd9Sstevel@tonic-gate * FALSE. If there is no authorization file, and the given Kerberos
2547c478bd9Sstevel@tonic-gate * name "server" translates to the same name as "luser" (using
2557c478bd9Sstevel@tonic-gate * krb5_aname_to_lname()), returns TRUE. Otherwise, if the authorization file
2567c478bd9Sstevel@tonic-gate * can't be accessed, returns FALSE. Otherwise, the file is read for
2577c478bd9Sstevel@tonic-gate * a matching principal name, instance, and realm. If one is found,
2587c478bd9Sstevel@tonic-gate * returns TRUE, if none is found, returns FALSE.
2597c478bd9Sstevel@tonic-gate *
2607c478bd9Sstevel@tonic-gate * The file entries are in the format produced by krb5_unparse_name(),
2617c478bd9Sstevel@tonic-gate * one entry per line.
2627c478bd9Sstevel@tonic-gate *
2637c478bd9Sstevel@tonic-gate */
2647c478bd9Sstevel@tonic-gate
265505d05c7Sgtb krb5_boolean KRB5_CALLCONV
krb5_kuserok(krb5_context context,krb5_principal principal,const char * luser)266505d05c7Sgtb krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
2677c478bd9Sstevel@tonic-gate {
2687c478bd9Sstevel@tonic-gate struct stat sbuf;
2697c478bd9Sstevel@tonic-gate struct passwd *pwd;
2707c478bd9Sstevel@tonic-gate char pbuf[MAXPATHLEN];
2717c478bd9Sstevel@tonic-gate krb5_boolean isok = FALSE;
2727c478bd9Sstevel@tonic-gate FILE *fp;
2737c478bd9Sstevel@tonic-gate char kuser[MAX_USERNAME];
2747c478bd9Sstevel@tonic-gate char *princname;
2757c478bd9Sstevel@tonic-gate char linebuf[BUFSIZ];
2767c478bd9Sstevel@tonic-gate char *newline;
277159d09a2SMark Phalan /* Solaris Kerberos */
2787c478bd9Sstevel@tonic-gate uid_t uid;
2797c478bd9Sstevel@tonic-gate int gobble;
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate /* no account => no access */
282505d05c7Sgtb char pwbuf[BUFSIZ];
283505d05c7Sgtb struct passwd pwx;
284159d09a2SMark Phalan if (k5_getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0)
2857c478bd9Sstevel@tonic-gate return(FALSE);
2867c478bd9Sstevel@tonic-gate (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
2877c478bd9Sstevel@tonic-gate pbuf[sizeof(pbuf) - 1] = '\0';
2887c478bd9Sstevel@tonic-gate (void) strncat(pbuf, "/.k5login", sizeof(pbuf) - 1 - strlen(pbuf));
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate if (access(pbuf, F_OK)) { /* not accessible */
2917c478bd9Sstevel@tonic-gate /*
292*48bbca81SDaniel Hoffman * if they're trying to log in as themself, and there is no .k5login file,
293*48bbca81SDaniel Hoffman * let them. First, have krb5 check it's rules. If no success,
2947c478bd9Sstevel@tonic-gate * search the gsscred table (the sequence here should be consistent
2957c478bd9Sstevel@tonic-gate * with the uid mappings done for gssd).
2967c478bd9Sstevel@tonic-gate */
2977c478bd9Sstevel@tonic-gate if (!(krb5_aname_to_localname(context, principal,
2987c478bd9Sstevel@tonic-gate sizeof(kuser), kuser))
2997c478bd9Sstevel@tonic-gate && (strcmp(kuser, luser) == 0)) {
300159d09a2SMark Phalan /* Solaris Kerberos */
3017c478bd9Sstevel@tonic-gate if (krb5_move_ccache(context, principal, pwd))
3027c478bd9Sstevel@tonic-gate return (FALSE);
3037c478bd9Sstevel@tonic-gate return(TRUE);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate if (krb5_gsscred(principal, &uid)) {
3077c478bd9Sstevel@tonic-gate #ifdef DEBUG
3087c478bd9Sstevel@tonic-gate char *princname;
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate (void)krb5_unparse_name(context, principal, &princname);
3117c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "gsscred mapped %s to %d expecting %d (%s)\n",
3127c478bd9Sstevel@tonic-gate princname, uid, pwd->pw_uid, luser);
3137c478bd9Sstevel@tonic-gate free(princname);
3147c478bd9Sstevel@tonic-gate #endif
3157c478bd9Sstevel@tonic-gate if (uid == pwd->pw_uid) {
3167c478bd9Sstevel@tonic-gate if (krb5_move_ccache(context, principal, pwd))
3177c478bd9Sstevel@tonic-gate return (FALSE);
3187c478bd9Sstevel@tonic-gate return (TRUE);
319004388ebScasper }
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate if (krb5_unparse_name(context, principal, &princname))
3247c478bd9Sstevel@tonic-gate return(FALSE); /* no hope of matching */
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate /* open ~/.k5login */
327159d09a2SMark Phalan /* Solaris Kerberos */
328004388ebScasper if ((fp = fopen(pbuf, "rF")) == NULL) {
3297c478bd9Sstevel@tonic-gate free(princname);
3307c478bd9Sstevel@tonic-gate return(FALSE);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate /*
3337c478bd9Sstevel@tonic-gate * For security reasons, the .k5login file must be owned either by
3347c478bd9Sstevel@tonic-gate * the user himself, or by root. Otherwise, don't grant access.
3357c478bd9Sstevel@tonic-gate */
3367c478bd9Sstevel@tonic-gate if (fstat(fileno(fp), &sbuf)) {
3377c478bd9Sstevel@tonic-gate fclose(fp);
3387c478bd9Sstevel@tonic-gate free(princname);
3397c478bd9Sstevel@tonic-gate return(FALSE);
3407c478bd9Sstevel@tonic-gate }
341159d09a2SMark Phalan if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid)) {
3427c478bd9Sstevel@tonic-gate fclose(fp);
3437c478bd9Sstevel@tonic-gate free(princname);
3447c478bd9Sstevel@tonic-gate return(FALSE);
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate /* check each line */
3487c478bd9Sstevel@tonic-gate while (!isok && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
3497c478bd9Sstevel@tonic-gate /* null-terminate the input string */
3507c478bd9Sstevel@tonic-gate linebuf[BUFSIZ-1] = '\0';
3517c478bd9Sstevel@tonic-gate newline = NULL;
3527c478bd9Sstevel@tonic-gate /* nuke the newline if it exists */
3537c478bd9Sstevel@tonic-gate if ((newline = strchr(linebuf, '\n')))
3547c478bd9Sstevel@tonic-gate *newline = '\0';
3557c478bd9Sstevel@tonic-gate if (!strcmp(linebuf, princname)) {
3567c478bd9Sstevel@tonic-gate isok = TRUE;
357159d09a2SMark Phalan /* Solaris Kerberos */
3587c478bd9Sstevel@tonic-gate if (krb5_move_ccache(context, principal, pwd))
3597c478bd9Sstevel@tonic-gate return (FALSE);
3607c478bd9Sstevel@tonic-gate continue;
3617c478bd9Sstevel@tonic-gate }
3627c478bd9Sstevel@tonic-gate /* clean up the rest of the line if necessary */
3637c478bd9Sstevel@tonic-gate if (!newline)
3647c478bd9Sstevel@tonic-gate while (((gobble = getc(fp)) != EOF) && gobble != '\n');
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate free(princname);
3677c478bd9Sstevel@tonic-gate fclose(fp);
3687c478bd9Sstevel@tonic-gate return(isok);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate
371159d09a2SMark Phalan /* Solaris Kerberos */
3727c478bd9Sstevel@tonic-gate OM_uint32
krb5_gss_userok(OM_uint32 * minor,const gss_name_t pname,const char * user,int * user_ok)373ab9b2e15Sgtb krb5_gss_userok(OM_uint32 *minor,
3747c478bd9Sstevel@tonic-gate const gss_name_t pname,
3757c478bd9Sstevel@tonic-gate const char *user,
3767c478bd9Sstevel@tonic-gate int *user_ok)
3777c478bd9Sstevel@tonic-gate {
378ab9b2e15Sgtb krb5_context ctxt;
379ab9b2e15Sgtb OM_uint32 kret;
380ab9b2e15Sgtb
3817c478bd9Sstevel@tonic-gate if (pname == NULL || user == NULL)
3827c478bd9Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ);
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate if (minor == NULL || user_ok == NULL)
3857c478bd9Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE);
386004388ebScasper
3877c478bd9Sstevel@tonic-gate *user_ok = 0;
3887c478bd9Sstevel@tonic-gate
389*48bbca81SDaniel Hoffman kret = krb5_gss_init_context(&ctxt);
390*48bbca81SDaniel Hoffman if (kret) {
391*48bbca81SDaniel Hoffman *minor = kret;
392*48bbca81SDaniel Hoffman return (GSS_S_FAILURE);
393ab9b2e15Sgtb }
394ab9b2e15Sgtb
3957c478bd9Sstevel@tonic-gate if (! kg_validate_name(pname)) {
396ab9b2e15Sgtb *minor = (OM_uint32) G_VALIDATE_FAILED;
397ab9b2e15Sgtb krb5_free_context(ctxt);
398ab9b2e15Sgtb return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate if (krb5_kuserok(ctxt, (krb5_principal) pname, user)) {
4027c478bd9Sstevel@tonic-gate *user_ok = 1;
4037c478bd9Sstevel@tonic-gate }
404ab9b2e15Sgtb
405ab9b2e15Sgtb krb5_free_context(ctxt);
4067c478bd9Sstevel@tonic-gate return (GSS_S_COMPLETE);
4077c478bd9Sstevel@tonic-gate }
408159d09a2SMark Phalan
409159d09a2SMark Phalan #else /* _WIN32 */
410159d09a2SMark Phalan
411159d09a2SMark Phalan /*
412159d09a2SMark Phalan * If the given Kerberos name "server" translates to the same name as "luser"
413159d09a2SMark Phalan * (using * krb5_aname_to_lname()), returns TRUE.
414159d09a2SMark Phalan */
415159d09a2SMark Phalan krb5_boolean KRB5_CALLCONV
krb5_kuserok(context,principal,luser)416159d09a2SMark Phalan krb5_kuserok(context, principal, luser)
417159d09a2SMark Phalan krb5_context context;
418159d09a2SMark Phalan krb5_principal principal;
419159d09a2SMark Phalan const char *luser;
420159d09a2SMark Phalan {
421159d09a2SMark Phalan char kuser[50];
422159d09a2SMark Phalan
423159d09a2SMark Phalan if (krb5_aname_to_localname(context, principal, sizeof(kuser), kuser))
424159d09a2SMark Phalan return FALSE;
425159d09a2SMark Phalan
426159d09a2SMark Phalan if (strcmp(kuser, luser) == 0)
427159d09a2SMark Phalan return TRUE;
428159d09a2SMark Phalan
429159d09a2SMark Phalan return FALSE;
430159d09a2SMark Phalan }
431159d09a2SMark Phalan #endif /* _WIN32 */
432