17c478bd9Sstevel@tonic-gate /*
2159d09a2SMark Phalan  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  * lib/krb5/os/init_ctx.c
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * Copyright 1994 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate  * All Rights Reserved.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
17*55fea89dSDan Cross  *
187c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
307c478bd9Sstevel@tonic-gate  * or implied warranty.
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * krb5_init_contex()
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #define NEED_WINDOWS
36159d09a2SMark Phalan 
37159d09a2SMark Phalan #include "k5-int.h"
38505d05c7Sgtb #ifndef _KERNEL
39505d05c7Sgtb #include "os-proto.h"
40159d09a2SMark Phalan #if 0 /* Solaris Kerberos */
41159d09a2SMark Phalan #include "prof_int.h"		/* XXX for profile_copy, not public yet */
42505d05c7Sgtb #endif
43159d09a2SMark Phalan errcode_t KRB5_CALLCONV profile_copy (profile_t, profile_t *);
44505d05c7Sgtb #endif
457c478bd9Sstevel@tonic-gate 
46505d05c7Sgtb #ifdef USE_LOGIN_LIBRARY
47505d05c7Sgtb #include "KerberosLoginPrivate.h"
48159d09a2SMark Phalan #endif
497c478bd9Sstevel@tonic-gate 
50505d05c7Sgtb #if defined(_WIN32)
51159d09a2SMark Phalan #include <winsock.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate static krb5_error_code
get_from_windows_dir(char ** pname)547c478bd9Sstevel@tonic-gate get_from_windows_dir(
557c478bd9Sstevel@tonic-gate     char **pname
567c478bd9Sstevel@tonic-gate     )
577c478bd9Sstevel@tonic-gate {
587c478bd9Sstevel@tonic-gate     UINT size = GetWindowsDirectory(0, 0);
597c478bd9Sstevel@tonic-gate     *pname = malloc(size + 1 +
607c478bd9Sstevel@tonic-gate                     strlen(DEFAULT_PROFILE_FILENAME) + 1);
617c478bd9Sstevel@tonic-gate     if (*pname)
627c478bd9Sstevel@tonic-gate     {
637c478bd9Sstevel@tonic-gate         GetWindowsDirectory(*pname, size);
647c478bd9Sstevel@tonic-gate         strcat(*pname, "\\");
657c478bd9Sstevel@tonic-gate         strcat(*pname, DEFAULT_PROFILE_FILENAME);
667c478bd9Sstevel@tonic-gate         return 0;
677c478bd9Sstevel@tonic-gate     } else {
687c478bd9Sstevel@tonic-gate         return KRB5_CONFIG_CANTOPEN;
697c478bd9Sstevel@tonic-gate     }
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate static krb5_error_code
get_from_module_dir(char ** pname)737c478bd9Sstevel@tonic-gate get_from_module_dir(
747c478bd9Sstevel@tonic-gate     char **pname
757c478bd9Sstevel@tonic-gate     )
767c478bd9Sstevel@tonic-gate {
777c478bd9Sstevel@tonic-gate     const DWORD size = 1024; /* fixed buffer */
787c478bd9Sstevel@tonic-gate     int found = 0;
797c478bd9Sstevel@tonic-gate     char *p;
807c478bd9Sstevel@tonic-gate     char *name;
817c478bd9Sstevel@tonic-gate     struct _stat s;
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate     *pname = 0;
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate     name = MALLOC(size);
867c478bd9Sstevel@tonic-gate     if (!name)
877c478bd9Sstevel@tonic-gate         return ENOMEM;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate     if (!GetModuleFileName(GetModuleHandle("krb5_32"), name, size))
907c478bd9Sstevel@tonic-gate         goto cleanup;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate     p = name + strlen(name);
937c478bd9Sstevel@tonic-gate     while ((p >= name) && (*p != '\\') && (*p != '/')) p--;
947c478bd9Sstevel@tonic-gate     if (p < name)
957c478bd9Sstevel@tonic-gate         goto cleanup;
967c478bd9Sstevel@tonic-gate     p++;
977c478bd9Sstevel@tonic-gate     strncpy(p, DEFAULT_PROFILE_FILENAME, size - (p - name));
987c478bd9Sstevel@tonic-gate     name[size - 1] = 0;
997c478bd9Sstevel@tonic-gate     found = !_stat(name, &s);
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate  cleanup:
1027c478bd9Sstevel@tonic-gate     if (found)
1037c478bd9Sstevel@tonic-gate         *pname = name;
1047c478bd9Sstevel@tonic-gate     else
1057c478bd9Sstevel@tonic-gate         if (name) FREE(name, size);
1067c478bd9Sstevel@tonic-gate     return 0;
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
1107c478bd9Sstevel@tonic-gate  * get_from_registry
1117c478bd9Sstevel@tonic-gate  *
1127c478bd9Sstevel@tonic-gate  * This will find a profile in the registry.  *pbuffer != 0 if we
1137c478bd9Sstevel@tonic-gate  * found something.  Make sure to free(*pbuffer) when done.  It will
1147c478bd9Sstevel@tonic-gate  * return an error code if there is an error the user should know
115*55fea89dSDan Cross  * about.  We maintain the invariant: return value != 0 =>
1167c478bd9Sstevel@tonic-gate  * *pbuffer == 0.
1177c478bd9Sstevel@tonic-gate  */
1187c478bd9Sstevel@tonic-gate static krb5_error_code
get_from_registry(char ** pbuffer,HKEY hBaseKey)1197c478bd9Sstevel@tonic-gate get_from_registry(
1207c478bd9Sstevel@tonic-gate     char** pbuffer,
1217c478bd9Sstevel@tonic-gate     HKEY hBaseKey
1227c478bd9Sstevel@tonic-gate     )
1237c478bd9Sstevel@tonic-gate {
1247c478bd9Sstevel@tonic-gate     HKEY hKey = 0;
1257c478bd9Sstevel@tonic-gate     LONG rc = 0;
1267c478bd9Sstevel@tonic-gate     DWORD size = 0;
1277c478bd9Sstevel@tonic-gate     krb5_error_code retval = 0;
1287c478bd9Sstevel@tonic-gate     const char *key_path = "Software\\MIT\\Kerberos5";
1297c478bd9Sstevel@tonic-gate     const char *value_name = "config";
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate     /* a wannabe assertion */
1327c478bd9Sstevel@tonic-gate     if (!pbuffer)
1337c478bd9Sstevel@tonic-gate     {
1347c478bd9Sstevel@tonic-gate         /*
1357c478bd9Sstevel@tonic-gate          * We have a programming error!  For now, we segfault :)
1367c478bd9Sstevel@tonic-gate          * There is no good mechanism to deal.
1377c478bd9Sstevel@tonic-gate          */
1387c478bd9Sstevel@tonic-gate     }
1397c478bd9Sstevel@tonic-gate     *pbuffer = 0;
1407c478bd9Sstevel@tonic-gate 
141*55fea89dSDan Cross     if ((rc = RegOpenKeyEx(hBaseKey, key_path, 0, KEY_QUERY_VALUE,
1427c478bd9Sstevel@tonic-gate                            &hKey)) != ERROR_SUCCESS)
1437c478bd9Sstevel@tonic-gate     {
1447c478bd9Sstevel@tonic-gate         /* not a real error */
1457c478bd9Sstevel@tonic-gate         goto cleanup;
1467c478bd9Sstevel@tonic-gate     }
1477c478bd9Sstevel@tonic-gate     rc = RegQueryValueEx(hKey, value_name, 0, 0, 0, &size);
1487c478bd9Sstevel@tonic-gate     if ((rc != ERROR_SUCCESS) &&  (rc != ERROR_MORE_DATA))
1497c478bd9Sstevel@tonic-gate     {
1507c478bd9Sstevel@tonic-gate         /* not a real error */
1517c478bd9Sstevel@tonic-gate         goto cleanup;
1527c478bd9Sstevel@tonic-gate     }
1537c478bd9Sstevel@tonic-gate     *pbuffer = MALLOC(size);
1547c478bd9Sstevel@tonic-gate     if (!*pbuffer)
1557c478bd9Sstevel@tonic-gate     {
1567c478bd9Sstevel@tonic-gate         retval = ENOMEM;
1577c478bd9Sstevel@tonic-gate         goto cleanup;
1587c478bd9Sstevel@tonic-gate     }
159*55fea89dSDan Cross     if ((rc = RegQueryValueEx(hKey, value_name, 0, 0, *pbuffer, &size)) !=
1607c478bd9Sstevel@tonic-gate         ERROR_SUCCESS)
1617c478bd9Sstevel@tonic-gate     {
1627c478bd9Sstevel@tonic-gate         /*
1637c478bd9Sstevel@tonic-gate          * Let's not call it a real error in case it disappears, but
1647c478bd9Sstevel@tonic-gate          * we need to free so that we say we did not find anything.
1657c478bd9Sstevel@tonic-gate          */
1667c478bd9Sstevel@tonic-gate         FREE(*pbuffer, size);
1677c478bd9Sstevel@tonic-gate         *pbuffer = 0;
1687c478bd9Sstevel@tonic-gate         goto cleanup;
1697c478bd9Sstevel@tonic-gate     }
1707c478bd9Sstevel@tonic-gate  cleanup:
1717c478bd9Sstevel@tonic-gate     if (hKey)
1727c478bd9Sstevel@tonic-gate         RegCloseKey(hKey);
1737c478bd9Sstevel@tonic-gate     if (retval && *pbuffer)
1747c478bd9Sstevel@tonic-gate     {
1757c478bd9Sstevel@tonic-gate         FREE(*pbuffer, size);
1767c478bd9Sstevel@tonic-gate         /* Let's say we did not find anything: */
1777c478bd9Sstevel@tonic-gate         *pbuffer = 0;
1787c478bd9Sstevel@tonic-gate     }
1797c478bd9Sstevel@tonic-gate     return retval;
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate 
182505d05c7Sgtb #endif /* _WIN32 */
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate #ifndef _KERNEL
1857c478bd9Sstevel@tonic-gate static void
free_filespecs(profile_filespec_t * files)186159d09a2SMark Phalan free_filespecs(profile_filespec_t *files)
1877c478bd9Sstevel@tonic-gate {
1887c478bd9Sstevel@tonic-gate     char **cp;
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate     if (files == 0)
1917c478bd9Sstevel@tonic-gate         return;
192*55fea89dSDan Cross 
1937c478bd9Sstevel@tonic-gate     for (cp = files; *cp; cp++)
1947c478bd9Sstevel@tonic-gate 	free(*cp);
1957c478bd9Sstevel@tonic-gate     free(files);
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate 
198*55fea89dSDan Cross /* This function is needed by KfM's KerberosPreferences API
199505d05c7Sgtb  * because it needs to be able to specify "secure" */
200505d05c7Sgtb krb5_error_code
os_get_default_config_files(profile_filespec_t ** pfiles,krb5_boolean secure)201505d05c7Sgtb os_get_default_config_files(profile_filespec_t **pfiles, krb5_boolean secure)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate     profile_filespec_t* files;
204505d05c7Sgtb #if defined(_WIN32)
2057c478bd9Sstevel@tonic-gate     krb5_error_code retval = 0;
2067c478bd9Sstevel@tonic-gate     char *name = 0;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate     if (!secure)
2097c478bd9Sstevel@tonic-gate     {
2107c478bd9Sstevel@tonic-gate         char *env = getenv("KRB5_CONFIG");
2117c478bd9Sstevel@tonic-gate         if (env)
2127c478bd9Sstevel@tonic-gate         {
2137c478bd9Sstevel@tonic-gate             name = malloc(strlen(env) + 1);
2147c478bd9Sstevel@tonic-gate             if (!name) return ENOMEM;
2157c478bd9Sstevel@tonic-gate             strcpy(name, env);
2167c478bd9Sstevel@tonic-gate         }
2177c478bd9Sstevel@tonic-gate     }
2187c478bd9Sstevel@tonic-gate     if (!name && !secure)
2197c478bd9Sstevel@tonic-gate     {
2207c478bd9Sstevel@tonic-gate         /* HKCU */
2217c478bd9Sstevel@tonic-gate         retval = get_from_registry(&name, HKEY_CURRENT_USER);
2227c478bd9Sstevel@tonic-gate         if (retval) return retval;
2237c478bd9Sstevel@tonic-gate     }
2247c478bd9Sstevel@tonic-gate     if (!name)
2257c478bd9Sstevel@tonic-gate     {
2267c478bd9Sstevel@tonic-gate         /* HKLM */
2277c478bd9Sstevel@tonic-gate         retval = get_from_registry(&name, HKEY_LOCAL_MACHINE);
2287c478bd9Sstevel@tonic-gate         if (retval) return retval;
2297c478bd9Sstevel@tonic-gate     }
2307c478bd9Sstevel@tonic-gate     if (!name && !secure)
2317c478bd9Sstevel@tonic-gate     {
2327c478bd9Sstevel@tonic-gate         /* module dir */
2337c478bd9Sstevel@tonic-gate         retval = get_from_module_dir(&name);
2347c478bd9Sstevel@tonic-gate         if (retval) return retval;
2357c478bd9Sstevel@tonic-gate     }
2367c478bd9Sstevel@tonic-gate     if (!name)
2377c478bd9Sstevel@tonic-gate     {
2387c478bd9Sstevel@tonic-gate         /* windows dir */
2397c478bd9Sstevel@tonic-gate         retval = get_from_windows_dir(&name);
2407c478bd9Sstevel@tonic-gate     }
2417c478bd9Sstevel@tonic-gate     if (retval)
2427c478bd9Sstevel@tonic-gate         return retval;
2437c478bd9Sstevel@tonic-gate     if (!name)
2447c478bd9Sstevel@tonic-gate         return KRB5_CONFIG_CANTOPEN; /* should never happen */
245*55fea89dSDan Cross 
2467c478bd9Sstevel@tonic-gate     files = malloc(2 * sizeof(char *));
2477c478bd9Sstevel@tonic-gate     files[0] = name;
2487c478bd9Sstevel@tonic-gate     files[1] = 0;
249505d05c7Sgtb #else /* !_WIN32 */
2507c478bd9Sstevel@tonic-gate     char* filepath = 0;
2517c478bd9Sstevel@tonic-gate     int n_entries, i;
252505d05c7Sgtb     unsigned int ent_len;
2537c478bd9Sstevel@tonic-gate     const char *s, *t;
2547c478bd9Sstevel@tonic-gate 
255159d09a2SMark Phalan #ifdef USE_LOGIN_LIBRARY
256159d09a2SMark Phalan     /* If __KLAllowHomeDirectoryAccess() == FALSE, we are probably
257159d09a2SMark Phalan         trying to authenticate to a fileserver for the user's homedir. */
258159d09a2SMark Phalan     if (!__KLAllowHomeDirectoryAccess ())
259159d09a2SMark Phalan 	secure = 1;
260159d09a2SMark Phalan #endif
261159d09a2SMark Phalan     if (secure) {
262159d09a2SMark Phalan 	filepath = DEFAULT_SECURE_PROFILE_PATH;
263*55fea89dSDan Cross     } else {
264159d09a2SMark Phalan         filepath = getenv("KRB5_CONFIG");
265159d09a2SMark Phalan         if (!filepath) filepath = DEFAULT_PROFILE_PATH;
266505d05c7Sgtb     }
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate     /* count the distinct filename components */
2697c478bd9Sstevel@tonic-gate     for(s = filepath, n_entries = 1; *s; s++) {
2707c478bd9Sstevel@tonic-gate         if (*s == ':')
2717c478bd9Sstevel@tonic-gate             n_entries++;
2727c478bd9Sstevel@tonic-gate     }
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate     /* the array is NULL terminated */
2757c478bd9Sstevel@tonic-gate     files = (char**) MALLOC((n_entries+1) * sizeof(char*));
2767c478bd9Sstevel@tonic-gate     if (files == 0)
2777c478bd9Sstevel@tonic-gate         return ENOMEM;
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate     /* measure, copy, and skip each one */
2807c478bd9Sstevel@tonic-gate     /*LINTED*/
2817c478bd9Sstevel@tonic-gate     for(s = filepath, i=0; (t = strchr(s, ':')) || (t=s+strlen(s)); s=t+1, i++)
2827c478bd9Sstevel@tonic-gate     {
2837c478bd9Sstevel@tonic-gate         ent_len = t-s;
2847c478bd9Sstevel@tonic-gate         files[i] = (char*) malloc(ent_len + 1);
2857c478bd9Sstevel@tonic-gate         if (files[i] == 0) {
2867c478bd9Sstevel@tonic-gate             /* if malloc fails, free the ones that worked */
2877c478bd9Sstevel@tonic-gate             while(--i >= 0) free(files[i]);
2887c478bd9Sstevel@tonic-gate             free(files);
2897c478bd9Sstevel@tonic-gate             return ENOMEM;
2907c478bd9Sstevel@tonic-gate         }
2917c478bd9Sstevel@tonic-gate         strncpy(files[i], s, ent_len);
2927c478bd9Sstevel@tonic-gate         files[i][ent_len] = 0;
2937c478bd9Sstevel@tonic-gate         if (*t == 0) {
2947c478bd9Sstevel@tonic-gate             i++;
2957c478bd9Sstevel@tonic-gate             break;
2967c478bd9Sstevel@tonic-gate         }
2977c478bd9Sstevel@tonic-gate     }
2987c478bd9Sstevel@tonic-gate     /* cap the array */
2997c478bd9Sstevel@tonic-gate     files[i] = 0;
300505d05c7Sgtb #endif /* !_WIN32 */
301505d05c7Sgtb     *pfiles = (profile_filespec_t *)files;
3027c478bd9Sstevel@tonic-gate     return 0;
3037c478bd9Sstevel@tonic-gate }
3047c478bd9Sstevel@tonic-gate 
30554925bf6Swillf static krb5_error_code
add_kdc_config_file(profile_filespec_t ** pfiles)30654925bf6Swillf add_kdc_config_file(profile_filespec_t **pfiles)
30754925bf6Swillf {
30854925bf6Swillf     char *file;
30954925bf6Swillf     size_t count;
31054925bf6Swillf     profile_filespec_t *newfiles;
31154925bf6Swillf 
31254925bf6Swillf     file = getenv(KDC_PROFILE_ENV);
31354925bf6Swillf     if (file == NULL)
31454925bf6Swillf 	file = DEFAULT_KDC_PROFILE;
31554925bf6Swillf 
31654925bf6Swillf     for (count = 0; (*pfiles)[count]; count++)
31754925bf6Swillf 	;
31854925bf6Swillf     count += 2;
31954925bf6Swillf     newfiles = malloc(count * sizeof(*newfiles));
32054925bf6Swillf     if (newfiles == NULL)
32154925bf6Swillf 	return errno;
32254925bf6Swillf     memcpy(newfiles + 1, *pfiles, (count-1) * sizeof(*newfiles));
32354925bf6Swillf     newfiles[0] = strdup(file);
32454925bf6Swillf     if (newfiles[0] == NULL) {
32554925bf6Swillf 	int e = errno;
32654925bf6Swillf 	free(newfiles);
32754925bf6Swillf 	return e;
32854925bf6Swillf     }
32954925bf6Swillf     free(*pfiles);
33054925bf6Swillf     *pfiles = newfiles;
33154925bf6Swillf     return 0;
33254925bf6Swillf }
3337c478bd9Sstevel@tonic-gate 
334159d09a2SMark Phalan 
335159d09a2SMark Phalan /* Set the profile paths in the context.  If secure is set to TRUE
336159d09a2SMark Phalan    then do not include user paths (from environment variables, etc).
337159d09a2SMark Phalan    If kdc is TRUE, include kdc.conf from whereever we expect to find
338159d09a2SMark Phalan    it.  */
3397c478bd9Sstevel@tonic-gate static krb5_error_code
os_init_paths(krb5_context ctx,krb5_boolean kdc)34054925bf6Swillf os_init_paths(krb5_context ctx, krb5_boolean kdc)
3417c478bd9Sstevel@tonic-gate {
3427c478bd9Sstevel@tonic-gate     krb5_error_code	retval = 0;
3437c478bd9Sstevel@tonic-gate     profile_filespec_t *files = 0;
3447c478bd9Sstevel@tonic-gate     krb5_boolean secure = ctx->profile_secure;
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
3477c478bd9Sstevel@tonic-gate     ctx->profile_in_memory = 0;
3487c478bd9Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate     retval = os_get_default_config_files(&files, secure);
3517c478bd9Sstevel@tonic-gate 
352159d09a2SMark Phalan     if (retval == 0 && kdc)
35354925bf6Swillf 	retval = add_kdc_config_file(&files);
35454925bf6Swillf 
3557c478bd9Sstevel@tonic-gate     if (!retval) {
3567c478bd9Sstevel@tonic-gate         retval = profile_init((const_profile_filespec_t *) files,
3577c478bd9Sstevel@tonic-gate 			      &ctx->profile);
358505d05c7Sgtb 
3597c478bd9Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
3607c478bd9Sstevel@tonic-gate         /* if none of the filenames can be opened use an empty profile */
3617c478bd9Sstevel@tonic-gate         if (retval == ENOENT) {
3627c478bd9Sstevel@tonic-gate             retval = profile_init(NULL, &ctx->profile);
3637c478bd9Sstevel@tonic-gate             if (!retval)
3647c478bd9Sstevel@tonic-gate                 ctx->profile_in_memory = 1;
365*55fea89dSDan Cross         }
3667c478bd9Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
3677c478bd9Sstevel@tonic-gate     }
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate     if (files)
3707c478bd9Sstevel@tonic-gate         free_filespecs(files);
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate     if (retval)
3737c478bd9Sstevel@tonic-gate         ctx->profile = 0;
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate     if (retval == ENOENT)
3767c478bd9Sstevel@tonic-gate         return KRB5_CONFIG_CANTOPEN;
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate     if ((retval == PROF_SECTION_NOTOP) ||
3797c478bd9Sstevel@tonic-gate         (retval == PROF_SECTION_SYNTAX) ||
3807c478bd9Sstevel@tonic-gate         (retval == PROF_RELATION_SYNTAX) ||
3817c478bd9Sstevel@tonic-gate         (retval == PROF_EXTRA_CBRACE) ||
3827c478bd9Sstevel@tonic-gate         (retval == PROF_MISSING_OBRACE))
3837c478bd9Sstevel@tonic-gate         return KRB5_CONFIG_BADFORMAT;
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate     return retval;
3867c478bd9Sstevel@tonic-gate }
3877c478bd9Sstevel@tonic-gate #endif /* !_KERNEL */
3887c478bd9Sstevel@tonic-gate 
38954925bf6Swillf /*ARGSUSED1*/
3907c478bd9Sstevel@tonic-gate krb5_error_code
krb5_os_init_context(krb5_context ctx,krb5_boolean kdc)39154925bf6Swillf krb5_os_init_context(krb5_context ctx, krb5_boolean kdc)
3927c478bd9Sstevel@tonic-gate {
3937c478bd9Sstevel@tonic-gate 	krb5_os_context os_ctx;
3947c478bd9Sstevel@tonic-gate 	krb5_error_code	retval = 0;
395159d09a2SMark Phalan #ifdef _WIN32
396159d09a2SMark Phalan     WORD wVersionRequested;
397159d09a2SMark Phalan     WSADATA wsaData;
398159d09a2SMark Phalan #endif /* _WIN32 */
3997c478bd9Sstevel@tonic-gate 
400505d05c7Sgtb 	os_ctx = ctx->os_context;
4017c478bd9Sstevel@tonic-gate 	os_ctx->magic = KV5M_OS_CONTEXT;
4027c478bd9Sstevel@tonic-gate 	os_ctx->time_offset = 0;
4037c478bd9Sstevel@tonic-gate 	os_ctx->usec_offset = 0;
4047c478bd9Sstevel@tonic-gate 	os_ctx->os_flags = 0;
4057c478bd9Sstevel@tonic-gate 	os_ctx->default_ccname = 0;
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate #ifndef _KERNEL
408159d09a2SMark Phalan 	ctx->vtbl = 0;
409159d09a2SMark Phalan 	PLUGIN_DIR_INIT(&ctx->libkrb5_plugins);
410159d09a2SMark Phalan 	PLUGIN_DIR_INIT(&ctx->preauth_plugins);
411159d09a2SMark Phalan 	ctx->preauth_context = NULL;
412505d05c7Sgtb 
41354925bf6Swillf 	retval = os_init_paths(ctx, kdc);
4147c478bd9Sstevel@tonic-gate 	/*
4157c478bd9Sstevel@tonic-gate 	 * If there's an error in the profile, return an error.  Just
4167c478bd9Sstevel@tonic-gate 	 * ignoring the error is a Bad Thing (tm).
4177c478bd9Sstevel@tonic-gate 	 */
418*55fea89dSDan Cross 
419159d09a2SMark Phalan         if (!retval) {
420159d09a2SMark Phalan                 krb5_cc_set_default_name(ctx, NULL);
421159d09a2SMark Phalan 
422159d09a2SMark Phalan #ifdef _WIN32
423*55fea89dSDan Cross                 /* We initialize winsock to version 1.1 but
424159d09a2SMark Phalan                  * we do not care if we succeed or fail.
425159d09a2SMark Phalan                  */
426159d09a2SMark Phalan                 wVersionRequested = 0x0101;
427159d09a2SMark Phalan                 WSAStartup (wVersionRequested, &wsaData);
428159d09a2SMark Phalan #endif /* _WIN32 */
429159d09a2SMark Phalan         }
4307c478bd9Sstevel@tonic-gate 
431159d09a2SMark Phalan #endif
4327c478bd9Sstevel@tonic-gate 	return retval;
4337c478bd9Sstevel@tonic-gate }
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate #ifndef _KERNEL
4367c478bd9Sstevel@tonic-gate 
437505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_profile(krb5_context ctx,profile_t * profile)438505d05c7Sgtb krb5_get_profile (krb5_context ctx, profile_t *profile)
4397c478bd9Sstevel@tonic-gate {
440159d09a2SMark Phalan     return profile_copy (ctx->profile, profile);
441*55fea89dSDan Cross }
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate #endif
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate #ifndef _KERNEL
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate krb5_error_code
krb5_set_config_files(krb5_context ctx,const char ** filenames)448505d05c7Sgtb krb5_set_config_files(krb5_context ctx, const char **filenames)
4497c478bd9Sstevel@tonic-gate {
4507c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
4517c478bd9Sstevel@tonic-gate 	profile_t	profile;
452*55fea89dSDan Cross 
4537c478bd9Sstevel@tonic-gate 	retval = profile_init(filenames, &profile);
4547c478bd9Sstevel@tonic-gate 	if (retval)
4557c478bd9Sstevel@tonic-gate 		return retval;
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 	if (ctx->profile)
4587c478bd9Sstevel@tonic-gate 		profile_release(ctx->profile);
4597c478bd9Sstevel@tonic-gate 	ctx->profile = profile;
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	return 0;
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate 
464505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_default_config_files(char *** pfilenames)465505d05c7Sgtb krb5_get_default_config_files(char ***pfilenames)
4667c478bd9Sstevel@tonic-gate {
4677c478bd9Sstevel@tonic-gate     if (!pfilenames)
4687c478bd9Sstevel@tonic-gate         return EINVAL;
4697c478bd9Sstevel@tonic-gate     return os_get_default_config_files(pfilenames, FALSE);
4707c478bd9Sstevel@tonic-gate }
4717c478bd9Sstevel@tonic-gate 
472505d05c7Sgtb void KRB5_CALLCONV
krb5_free_config_files(char ** filenames)473505d05c7Sgtb krb5_free_config_files(char **filenames)
4747c478bd9Sstevel@tonic-gate {
4757c478bd9Sstevel@tonic-gate     free_filespecs(filenames);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate #ifndef _KERNEL
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate krb5_error_code
krb5_secure_config_files(krb5_context ctx)483505d05c7Sgtb krb5_secure_config_files(krb5_context ctx)
4847c478bd9Sstevel@tonic-gate {
4857c478bd9Sstevel@tonic-gate 	/* Obsolete interface; always return an error.
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 	   This function should be removed next time a major version
4887c478bd9Sstevel@tonic-gate 	   number change happens.  */
4897c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
490*55fea89dSDan Cross 
4917c478bd9Sstevel@tonic-gate 	if (ctx->profile) {
4927c478bd9Sstevel@tonic-gate 		profile_release(ctx->profile);
4937c478bd9Sstevel@tonic-gate 		ctx->profile = 0;
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	ctx->profile_secure = TRUE;
49754925bf6Swillf 	retval = os_init_paths(ctx, FALSE);
4987c478bd9Sstevel@tonic-gate 	if (retval)
4997c478bd9Sstevel@tonic-gate 		return retval;
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate 	return KRB5_OBSOLETE_FN;
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate void
krb5_os_free_context(krb5_context ctx)507505d05c7Sgtb krb5_os_free_context(krb5_context ctx)
5087c478bd9Sstevel@tonic-gate {
5097c478bd9Sstevel@tonic-gate 	krb5_os_context os_ctx;
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate 	os_ctx = ctx->os_context;
512*55fea89dSDan Cross 
513159d09a2SMark Phalan 	if (os_ctx->default_ccname) {
5147c478bd9Sstevel@tonic-gate 		FREE(os_ctx->default_ccname,
5157c478bd9Sstevel@tonic-gate 			strlen(os_ctx->default_ccname) + 1);
5167c478bd9Sstevel@tonic-gate                 os_ctx->default_ccname = 0;
5177c478bd9Sstevel@tonic-gate         }
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 	os_ctx->magic = 0;
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate #ifndef _KERNEL
5227c478bd9Sstevel@tonic-gate 	if (ctx->profile) {
523159d09a2SMark Phalan 		profile_release(ctx->profile);
5247c478bd9Sstevel@tonic-gate 	    ctx->profile = 0;
5257c478bd9Sstevel@tonic-gate 	}
526159d09a2SMark Phalan 
527159d09a2SMark Phalan 	if (ctx->preauth_context) {
528159d09a2SMark Phalan 		krb5_free_preauth_context(ctx);
529159d09a2SMark Phalan 		ctx->preauth_context = NULL;
530159d09a2SMark Phalan 	}
531159d09a2SMark Phalan 	krb5int_close_plugin_dirs (&ctx->preauth_plugins);
532159d09a2SMark Phalan 	krb5int_close_plugin_dirs (&ctx->libkrb5_plugins);
533159d09a2SMark Phalan 
5347c478bd9Sstevel@tonic-gate #endif
5357c478bd9Sstevel@tonic-gate }
536159d09a2SMark Phalan #ifdef _WIN32
537159d09a2SMark Phalan         WSACleanup();
538159d09a2SMark Phalan #endif /* _WIN32 */
539