12830Sdjl /*
22830Sdjl * CDDL HEADER START
32830Sdjl *
42830Sdjl * The contents of this file are subject to the terms of the
52830Sdjl * Common Development and Distribution License (the "License").
62830Sdjl * You may not use this file except in compliance with the License.
72830Sdjl *
82830Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92830Sdjl * or http://www.opensolaris.org/os/licensing.
102830Sdjl * See the License for the specific language governing permissions
112830Sdjl * and limitations under the License.
122830Sdjl *
132830Sdjl * When distributing Covered Code, include this CDDL HEADER in each
142830Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152830Sdjl * If applicable, add the following below this CDDL HEADER, with the
162830Sdjl * fields enclosed by brackets "[]" replaced with your own identifying
172830Sdjl * information: Portions Copyright [yyyy] [name of copyright owner]
182830Sdjl *
192830Sdjl * CDDL HEADER END
202830Sdjl */
21*12823SJulian.Pullen@Sun.COM
222830Sdjl /*
23*12823SJulian.Pullen@Sun.COM * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
242830Sdjl */
252830Sdjl
262830Sdjl #include <stdio.h>
272830Sdjl #include <stdlib.h>
282830Sdjl #include <strings.h>
292830Sdjl #include <sys/types.h>
302830Sdjl #include <sys/stat.h>
312830Sdjl #include <unistd.h>
322830Sdjl #include <thread.h>
332830Sdjl #include <synch.h>
342830Sdjl #include <sasl/sasl.h>
352830Sdjl #include <sys/socket.h>
362830Sdjl #include <netdb.h>
372830Sdjl #include <netinet/in.h>
382830Sdjl #include <arpa/inet.h>
392830Sdjl #include <syslog.h>
402830Sdjl #include <ctype.h>
412830Sdjl #include <libscf.h>
422830Sdjl #include <libintl.h>
432830Sdjl #include <locale.h>
442830Sdjl #include "ns_sldap.h"
452830Sdjl #include "ns_internal.h"
462830Sdjl
472830Sdjl static int self_gssapi_only = 0;
482830Sdjl static mutex_t self_gssapi_only_lock = DEFAULTMUTEX;
492830Sdjl
502830Sdjl #define DNS_FMRI "svc:/network/dns/client:default"
512830Sdjl #define MSGSIZE 256
522830Sdjl
532830Sdjl #define NSSWITCH_CONF "/etc/nsswitch.conf"
542830Sdjl
552830Sdjl /*
562830Sdjl * Error Handling
572830Sdjl */
582830Sdjl #define CLIENT_FPRINTF if (mode_verbose && !mode_quiet) (void) fprintf
592830Sdjl
602830Sdjl /*
612830Sdjl * nscd calls this function to set self_gssapi_only flag so libsldap performs
622830Sdjl * sasl/GSSAPI bind only. Also see comments of __ns_ldap_self_gssapi_config.
632830Sdjl *
642830Sdjl * Input: flag 0 use any kind of connection
652830Sdjl * 1 use self/gssapi connection only
662830Sdjl */
672830Sdjl void
__ns_ldap_self_gssapi_only_set(int flag)682830Sdjl __ns_ldap_self_gssapi_only_set(int flag) {
692830Sdjl (void) mutex_lock(&self_gssapi_only_lock);
702830Sdjl self_gssapi_only = flag;
712830Sdjl (void) mutex_unlock(&self_gssapi_only_lock);
722830Sdjl }
73*12823SJulian.Pullen@Sun.COM
742830Sdjl /*
752830Sdjl * Get the flag value of self_gssapi_only
762830Sdjl */
772830Sdjl int
__s_api_self_gssapi_only_get(void)782830Sdjl __s_api_self_gssapi_only_get(void) {
792830Sdjl int flag;
802830Sdjl (void) mutex_lock(&self_gssapi_only_lock);
812830Sdjl flag = self_gssapi_only;
822830Sdjl (void) mutex_unlock(&self_gssapi_only_lock);
832830Sdjl return (flag);
842830Sdjl }
85*12823SJulian.Pullen@Sun.COM
862830Sdjl /*
872830Sdjl * nscd calls this function to detect the current native ldap configuration.
882830Sdjl * The output are
892830Sdjl * NS_LDAP_SELF_GSSAPI_CONFIG_NONE: No credential level self and
902830Sdjl * no authentication method sasl/GSSAPI is
912830Sdjl * configured.
922830Sdjl * NS_LDAP_SELF_GSSAPI_CONFIG_ONLY: Only credential level self and
932830Sdjl * authentication method sasl/GSSAPI are
942830Sdjl * configured.
952830Sdjl * NS_LDAP_SELF_GSSAPI_CONFIG_MIXED: More than one credential level are
962830Sdjl * configured, including self.
972830Sdjl * More than one authentication method
982830Sdjl * are configured, including sasl/GSSAPI.
992830Sdjl *
1002830Sdjl * __s_api_crosscheck makes sure self and sasl/GSSAPI pair up if they do
1012830Sdjl * get configured.
1022830Sdjl *
1032830Sdjl * When nscd detects it's MIXED case, it calls __ns_ldap_self_gssapi_only_set
1042830Sdjl * to force libsldap to do sasl/GSSAPI bind only for per-user lookup.
1052830Sdjl *
1062830Sdjl * Return: NS_LDAP_SUCCESS
1072830Sdjl * OTHERWISE - FAILURE
1082830Sdjl *
1092830Sdjl * Output: config. See comments above.
1102830Sdjl *
1112830Sdjl */
1122830Sdjl int
__ns_ldap_self_gssapi_config(ns_ldap_self_gssapi_config_t * config)1132830Sdjl __ns_ldap_self_gssapi_config(ns_ldap_self_gssapi_config_t *config) {
1142830Sdjl int self = 0, other_level = 0, gssapi = 0, other_method = 0;
1152830Sdjl ns_auth_t **aMethod = NULL, **aNext = NULL;
1162830Sdjl int **cLevel = NULL, **cNext = NULL, rc;
1172830Sdjl ns_ldap_error_t *errp = NULL;
1183015Schinlong FILE *fp;
1192830Sdjl
1202830Sdjl if (config == NULL)
1212830Sdjl return (NS_LDAP_INVALID_PARAM);
1222830Sdjl else
1232830Sdjl *config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE;
1242830Sdjl
1253015Schinlong /*
1263015Schinlong * If config files don't exist, return NS_LDAP_CONFIG.
1273015Schinlong * It's the same return code __ns_ldap_getParam
1283015Schinlong * returns in the same situation.
1293015Schinlong */
1303015Schinlong if ((fp = fopen(NSCONFIGFILE, "rF")) == NULL)
1313015Schinlong return (NS_LDAP_CONFIG);
1323015Schinlong else
1333015Schinlong (void) fclose(fp);
1343015Schinlong if ((fp = fopen(NSCREDFILE, "rF")) == NULL)
1353015Schinlong return (NS_LDAP_CONFIG);
1363015Schinlong else
1373015Schinlong (void) fclose(fp);
1383015Schinlong
1392830Sdjl /* Get the credential level list */
1402830Sdjl if ((rc = __ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P,
1412830Sdjl (void ***)&cLevel, &errp)) != NS_LDAP_SUCCESS) {
1422830Sdjl if (errp)
1432830Sdjl (void) __ns_ldap_freeError(&errp);
1442830Sdjl if (cLevel)
1452830Sdjl (void) __ns_ldap_freeParam((void ***)&cLevel);
1462830Sdjl return (rc);
1472830Sdjl }
1482830Sdjl if (errp)
1492830Sdjl (void) __ns_ldap_freeError(&errp);
1502830Sdjl /* Get the authentication method list */
1512830Sdjl if ((rc = __ns_ldap_getParam(NS_LDAP_AUTH_P,
1522830Sdjl (void ***)&aMethod, &errp)) != NS_LDAP_SUCCESS) {
1532830Sdjl if (errp)
1542830Sdjl (void) __ns_ldap_freeError(&errp);
1552830Sdjl if (cLevel)
1562830Sdjl (void) __ns_ldap_freeParam((void ***)&cLevel);
1572830Sdjl if (aMethod)
1582830Sdjl (void) __ns_ldap_freeParam((void ***)&aMethod);
1592830Sdjl return (rc);
1602830Sdjl }
1612830Sdjl if (errp)
1622830Sdjl (void) __ns_ldap_freeError(&errp);
1632830Sdjl
1642830Sdjl if (cLevel == NULL || aMethod == NULL) {
1652830Sdjl if (cLevel)
1662830Sdjl (void) __ns_ldap_freeParam((void ***)&cLevel);
1672830Sdjl if (aMethod)
1682830Sdjl (void) __ns_ldap_freeParam((void ***)&aMethod);
1692830Sdjl return (NS_LDAP_SUCCESS);
1702830Sdjl }
1712830Sdjl
1722830Sdjl for (cNext = cLevel; *cNext != NULL; cNext++) {
1732830Sdjl if (**cNext == NS_LDAP_CRED_SELF)
1742830Sdjl self++;
1752830Sdjl else
1762830Sdjl other_level++;
1772830Sdjl }
1782830Sdjl for (aNext = aMethod; *aNext != NULL; aNext++) {
1792830Sdjl if ((*aNext)->saslmech == NS_LDAP_SASL_GSSAPI)
1802830Sdjl gssapi++;
1812830Sdjl else
1822830Sdjl other_method++;
1832830Sdjl }
1842830Sdjl
1852830Sdjl if (self > 0 && gssapi > 0) {
1862830Sdjl if (other_level == 0 && other_method == 0)
1872830Sdjl *config = NS_LDAP_SELF_GSSAPI_CONFIG_ONLY;
1882830Sdjl else
1892830Sdjl *config = NS_LDAP_SELF_GSSAPI_CONFIG_MIXED;
1902830Sdjl }
1912830Sdjl
1922830Sdjl if (cLevel)
1932830Sdjl (void) __ns_ldap_freeParam((void ***)&cLevel);
1942830Sdjl if (aMethod)
1952830Sdjl (void) __ns_ldap_freeParam((void ***)&aMethod);
1962830Sdjl return (NS_LDAP_SUCCESS);
1972830Sdjl }
1982830Sdjl
1992830Sdjl int
__s_api_sasl_bind_callback(LDAP * ld,unsigned flags,void * defaults,void * in)2002830Sdjl __s_api_sasl_bind_callback(
2012830Sdjl /* LINTED E_FUNC_ARG_UNUSED */
2022830Sdjl LDAP *ld,
2032830Sdjl /* LINTED E_FUNC_ARG_UNUSED */
2042830Sdjl unsigned flags,
2052830Sdjl void *defaults,
2062830Sdjl void *in)
2072830Sdjl {
2082830Sdjl char *ret = NULL;
2092830Sdjl sasl_interact_t *interact = in;
2102830Sdjl ns_sasl_cb_param_t *cred = (ns_sasl_cb_param_t *)defaults;
2112830Sdjl
2122830Sdjl
2132830Sdjl while (interact->id != SASL_CB_LIST_END) {
2142830Sdjl
2152830Sdjl switch (interact->id) {
2162830Sdjl
2172830Sdjl case SASL_CB_GETREALM:
2182830Sdjl ret = cred->realm;
2192830Sdjl break;
2202830Sdjl case SASL_CB_AUTHNAME:
2212830Sdjl ret = cred->authid;
2222830Sdjl break;
2232830Sdjl case SASL_CB_PASS:
2242830Sdjl ret = cred->passwd;
2252830Sdjl break;
2262830Sdjl case SASL_CB_USER:
2272830Sdjl ret = cred->authzid;
2282830Sdjl break;
2292830Sdjl case SASL_CB_NOECHOPROMPT:
2302830Sdjl case SASL_CB_ECHOPROMPT:
2312830Sdjl default:
2322830Sdjl break;
2332830Sdjl }
2342830Sdjl
2352830Sdjl if (ret) {
23612022SMichen.Chang@Sun.COM /*
23712022SMichen.Chang@Sun.COM * No need to do strdup(ret), the data is always
23812022SMichen.Chang@Sun.COM * available in 'defaults' and libldap won't
23912022SMichen.Chang@Sun.COM * free it either. strdup(ret) causes memory
24012022SMichen.Chang@Sun.COM * leak.
24112022SMichen.Chang@Sun.COM */
24212022SMichen.Chang@Sun.COM interact->result = ret;
2432830Sdjl interact->len = strlen(ret);
2442830Sdjl } else {
2452830Sdjl interact->result = NULL;
2462830Sdjl interact->len = 0;
2472830Sdjl }
2482830Sdjl interact++;
2492830Sdjl }
2502830Sdjl
2512830Sdjl return (LDAP_SUCCESS);
2522830Sdjl }
2532830Sdjl
2542830Sdjl /*
2552830Sdjl * Find "dbase: service1 [...] services2" in fname and return
2562830Sdjl * " service1 [...] services2"
2572830Sdjl * e.g.
2582830Sdjl * Find "hosts: files dns" and return " files dns"
2592830Sdjl */
2602830Sdjl static char *
__ns_nsw_getconfig(const char * dbase,const char * fname,int * errp)2612830Sdjl __ns_nsw_getconfig(const char *dbase, const char *fname, int *errp)
2622830Sdjl {
2632830Sdjl FILE *fp = NULL;
2642830Sdjl char *linep, *retp = NULL;
2652830Sdjl char lineq[BUFSIZ], db_colon[BUFSIZ];
2662830Sdjl
2672830Sdjl if ((fp = fopen(fname, "rF")) == NULL) {
2682830Sdjl *errp = NS_LDAP_CONFIG;
2692830Sdjl return (NULL);
2702830Sdjl }
2712830Sdjl *errp = NS_LDAP_SUCCESS;
2722830Sdjl
2732830Sdjl while (linep = fgets(lineq, BUFSIZ, fp)) {
2742830Sdjl char *tokenp, *comment;
2752830Sdjl
2762830Sdjl /*
2772830Sdjl * Ignore portion of line following the comment character '#'.
2782830Sdjl */
2792830Sdjl if ((comment = strchr(linep, '#')) != NULL) {
2802830Sdjl *comment = '\0';
2812830Sdjl }
2822830Sdjl if ((*linep == '\0') || isspace(*linep)) {
2832830Sdjl continue;
2842830Sdjl }
2852830Sdjl (void) snprintf(db_colon, BUFSIZ, "%s:", dbase);
2862830Sdjl if ((tokenp = strstr(linep, db_colon)) == NULL) {
2872830Sdjl continue; /* ignore this line */
2882830Sdjl } else {
2892830Sdjl /* skip "dbase:" */
2902830Sdjl retp = strdup(tokenp + strlen(db_colon));
2912830Sdjl if (retp == NULL)
2922830Sdjl *errp = NS_LDAP_MEMORY;
2932830Sdjl }
2942830Sdjl }
2952830Sdjl
2962830Sdjl (void) fclose(fp);
2972830Sdjl return (retp);
2982830Sdjl }
2992830Sdjl /*
3002830Sdjl * Test the configurations of the "hosts" and "ipnodes"
3012830Sdjl * dns has to be present and appear before ldap
3022830Sdjl * e.g.
3032830Sdjl * "dns" , "dns files" "dns ldap files", "files dns" are allowed.
3042830Sdjl *
3052830Sdjl * Kerberos requires dns or it'd fail.
3062830Sdjl */
3072830Sdjl static int
test_dns_nsswitch(int foreground,const char * fname,ns_ldap_error_t ** errpp)3082830Sdjl test_dns_nsswitch(int foreground,
3092830Sdjl const char *fname,
3102830Sdjl ns_ldap_error_t **errpp) {
3112830Sdjl int ldap, dns, i, pserr, rc = NS_LDAP_SUCCESS;
3122830Sdjl char *db[3] = {"hosts", "ipnodes", NULL};
3132830Sdjl char buf[MSGSIZE], *conf = NULL, *token = NULL, *last = NULL;
3142830Sdjl
3152830Sdjl for (i = 0; db[i] != NULL; i++) {
3162830Sdjl conf = __ns_nsw_getconfig(db[i], fname, &pserr);
3172830Sdjl
3182830Sdjl if (conf == NULL) {
3192830Sdjl (void) snprintf(buf, MSGSIZE,
3202830Sdjl gettext("Parsing %s to find \"%s:\" "
3212830Sdjl "failed. err: %d"),
3222830Sdjl fname, db[i], pserr);
3232830Sdjl if (foreground) {
3242830Sdjl (void) fprintf(stderr, "%s\n", buf);
3252830Sdjl } else {
3262830Sdjl MKERROR(LOG_ERR, *errpp, NS_LDAP_CONFIG,
3272830Sdjl strdup(buf), NS_LDAP_MEMORY);
3282830Sdjl }
3292830Sdjl return (pserr);
3302830Sdjl }
3312830Sdjl ldap = dns = 0;
3322830Sdjl token = strtok_r(conf, " ", &last);
3332830Sdjl while (token != NULL) {
3342830Sdjl if (strncmp(token, "dns", 3) == 0) {
3352830Sdjl if (ldap) {
3362830Sdjl (void) snprintf(buf, MSGSIZE,
3372830Sdjl gettext("%s: ldap can't appear "
3382830Sdjl "before dns"), db[i]);
3392830Sdjl if (foreground) {
3402830Sdjl (void) fprintf(stderr,
3412830Sdjl "start: %s\n",
3422830Sdjl buf);
3432830Sdjl } else {
3442830Sdjl MKERROR(LOG_ERR, *errpp,
3452830Sdjl NS_LDAP_CONFIG,
3462830Sdjl strdup(buf),
3472830Sdjl NS_LDAP_MEMORY);
3482830Sdjl }
3492830Sdjl free(conf);
3502830Sdjl return (NS_LDAP_CONFIG);
3512830Sdjl } else {
3522830Sdjl dns++;
3532830Sdjl }
3542830Sdjl } else if (strncmp(token, "ldap", 4) == 0) {
3552830Sdjl ldap++;
3562830Sdjl }
3572830Sdjl /* next token */
3582830Sdjl token = strtok_r(NULL, " ", &last);
3592830Sdjl }
3602830Sdjl if (conf) {
3612830Sdjl free(conf);
3622830Sdjl conf = NULL;
3632830Sdjl }
3642830Sdjl if (!dns) {
3652830Sdjl (void) snprintf(buf, MSGSIZE,
3662830Sdjl gettext("%s: dns is not defined in "
3672830Sdjl "%s"), db[i], fname);
3682830Sdjl if (foreground) {
3692830Sdjl (void) fprintf(stderr, "start: %s\n", buf);
3702830Sdjl } else {
3712830Sdjl MKERROR(LOG_ERR, *errpp, NS_LDAP_CONFIG,
3722830Sdjl strdup(buf), NS_LDAP_MEMORY);
3732830Sdjl }
3742830Sdjl rc = NS_LDAP_CONFIG;
3752830Sdjl break;
3762830Sdjl }
3772830Sdjl }
3782830Sdjl return (rc);
3792830Sdjl }
3802830Sdjl
3812830Sdjl static boolean_t
is_service(const char * fmri,const char * state)3822830Sdjl is_service(const char *fmri, const char *state) {
3832830Sdjl char *st;
3842830Sdjl boolean_t result = B_FALSE;
3852830Sdjl
3862830Sdjl if ((st = smf_get_state(fmri)) != NULL) {
3872830Sdjl if (strcmp(st, state) == 0)
3882830Sdjl result = B_TRUE;
3892830Sdjl free(st);
3902830Sdjl }
3912830Sdjl return (result);
3922830Sdjl }
3932830Sdjl
3942830Sdjl
3952830Sdjl /*
3962830Sdjl * This function checks dns prerequisites for sasl/GSSAPI bind.
3972830Sdjl * It's called only if config == NS_LDAP_SELF_GSSAPI_CONFIG_ONLY ||
3982830Sdjl * config == NS_LDAP_SELF_GSSAPI_CONFIG_MIXED.
3992830Sdjl */
4002830Sdjl int
__ns_ldap_check_dns_preq(int foreground,int mode_verbose,int mode_quiet,const char * fname,ns_ldap_self_gssapi_config_t config,ns_ldap_error_t ** errpp)4012830Sdjl __ns_ldap_check_dns_preq(int foreground,
4022830Sdjl int mode_verbose,
4032830Sdjl int mode_quiet,
4042830Sdjl const char *fname,
4052830Sdjl ns_ldap_self_gssapi_config_t config,
4062830Sdjl ns_ldap_error_t **errpp) {
4072830Sdjl
4082830Sdjl char buf[MSGSIZE];
4092830Sdjl int retcode = NS_LDAP_SUCCESS;
4102830Sdjl int loglevel;
4112830Sdjl
4122830Sdjl if (errpp)
4132830Sdjl *errpp = NULL;
4142830Sdjl else
4152830Sdjl return (NS_LDAP_INVALID_PARAM);
4162830Sdjl
4172830Sdjl if (config == NS_LDAP_SELF_GSSAPI_CONFIG_NONE)
4182830Sdjl /* Shouldn't happen. Check this value just in case */
4192830Sdjl return (NS_LDAP_SUCCESS);
4202830Sdjl
4212830Sdjl if ((retcode = test_dns_nsswitch(foreground, fname, errpp)) !=
4222830Sdjl NS_LDAP_SUCCESS)
4232830Sdjl return (retcode);
4242830Sdjl
4252830Sdjl if (is_service(DNS_FMRI, SCF_STATE_STRING_ONLINE)) {
4262830Sdjl if (foreground) {
4272830Sdjl CLIENT_FPRINTF(stdout, "start: %s\n",
4282830Sdjl gettext("DNS client is enabled"));
4292830Sdjl } else {
4304048Schinlong syslog(LOG_INFO, "libsldap: %s",
4312830Sdjl gettext("DNS client is enabled"));
4322830Sdjl }
4332830Sdjl return (NS_LDAP_SUCCESS);
4342830Sdjl } else {
4352830Sdjl if (config == NS_LDAP_SELF_GSSAPI_CONFIG_ONLY) {
4362830Sdjl (void) snprintf(buf, MSGSIZE,
4372830Sdjl gettext("%s: DNS client is not enabled. "
4382830Sdjl "Run \"svcadm enable %s\". %s."),
4392830Sdjl "Error", DNS_FMRI, "Abort");
4402830Sdjl loglevel = LOG_ERR;
4412830Sdjl retcode = NS_LDAP_CONFIG;
4422830Sdjl } else if (config == NS_LDAP_SELF_GSSAPI_CONFIG_MIXED) {
4432830Sdjl (void) snprintf(buf, MSGSIZE,
4442830Sdjl gettext("%s: DNS client is not enabled. "
4452830Sdjl "Run \"svcadm enable %s\". %s."
4462830Sdjl "Fall back to other cred level/bind. "),
4472830Sdjl "Warning", DNS_FMRI, "Continue");
4482830Sdjl loglevel = LOG_INFO;
4492830Sdjl retcode = NS_LDAP_SUCCESS;
4502830Sdjl }
4512830Sdjl
4522830Sdjl if (foreground) {
4532830Sdjl (void) fprintf(stderr, "start: %s\n", buf);
4542830Sdjl } else {
4552830Sdjl MKERROR(loglevel, *errpp, retcode, strdup(buf),
4562830Sdjl NS_LDAP_MEMORY);
4572830Sdjl }
4582830Sdjl return (retcode);
4592830Sdjl }
4602830Sdjl }
4612830Sdjl
4622830Sdjl /*
4632830Sdjl * Check if sasl/GSSAPI works
4642830Sdjl */
4652830Sdjl int
__ns_ldap_check_gssapi_preq(int foreground,int mode_verbose,int mode_quiet,ns_ldap_self_gssapi_config_t config,ns_ldap_error_t ** errpp)4662830Sdjl __ns_ldap_check_gssapi_preq(int foreground,
4672830Sdjl int mode_verbose,
4682830Sdjl int mode_quiet,
4692830Sdjl ns_ldap_self_gssapi_config_t config,
4702830Sdjl ns_ldap_error_t **errpp) {
4712830Sdjl
4722830Sdjl int rc;
4732830Sdjl char *attr[2] = {"dn", NULL}, buf[MSGSIZE];
4742830Sdjl ns_cred_t cred;
4752830Sdjl ns_ldap_result_t *result = NULL;
4762830Sdjl int loglevel;
4772830Sdjl
4782830Sdjl if (errpp)
4792830Sdjl *errpp = NULL;
4802830Sdjl else
4812830Sdjl return (NS_LDAP_INVALID_PARAM);
4822830Sdjl
4832830Sdjl if (config == NS_LDAP_SELF_GSSAPI_CONFIG_NONE)
4842830Sdjl /* Don't need to check */
4852830Sdjl return (NS_LDAP_SUCCESS);
4862830Sdjl
4872830Sdjl (void) memset(&cred, 0, sizeof (ns_cred_t));
4882830Sdjl
4892830Sdjl cred.auth.type = NS_LDAP_AUTH_SASL;
4902830Sdjl cred.auth.tlstype = NS_LDAP_TLS_NONE;
4912830Sdjl cred.auth.saslmech = NS_LDAP_SASL_GSSAPI;
4922830Sdjl
4932830Sdjl rc = __ns_ldap_list(NULL, (const char *)"objectclass=*",
4942830Sdjl NULL, (const char **)attr, &cred,
4952830Sdjl NS_LDAP_SCOPE_BASE, &result, errpp, NULL, NULL);
4962830Sdjl if (result)
4972830Sdjl (void) __ns_ldap_freeResult(&result);
4982830Sdjl
4992830Sdjl if (rc == NS_LDAP_SUCCESS) {
5002830Sdjl if (foreground) {
5012830Sdjl CLIENT_FPRINTF(stdout, "start: %s\n",
5022830Sdjl gettext("sasl/GSSAPI bind works"));
5032830Sdjl } else {
5044048Schinlong syslog(LOG_INFO, "libsldap: %s",
5052830Sdjl gettext("sasl/GSSAPI bind works"));
5062830Sdjl }
5072830Sdjl return (NS_LDAP_SUCCESS);
5082830Sdjl } else {
5092830Sdjl if (config == NS_LDAP_SELF_GSSAPI_CONFIG_ONLY) {
5102830Sdjl (void) snprintf(buf, MSGSIZE,
5112830Sdjl gettext("%s: sasl/GSSAPI bind is not "
5122830Sdjl "working. %s."),
5132830Sdjl "Error", "Abort");
5142830Sdjl loglevel = LOG_ERR;
5152830Sdjl } else if (config == NS_LDAP_SELF_GSSAPI_CONFIG_MIXED) {
5162830Sdjl (void) snprintf(buf, MSGSIZE,
5172830Sdjl gettext("%s: sasl/GSSAPI bind is not "
5182830Sdjl "working. Fall back to other cred "
5192830Sdjl "level/bind. %s."),
5202830Sdjl "Warning", "Continue");
5212830Sdjl loglevel = LOG_INFO;
5222830Sdjl /* reset return code */
5232830Sdjl rc = NS_LDAP_SUCCESS;
5242830Sdjl }
5252830Sdjl
5262830Sdjl if (foreground) {
5272830Sdjl (void) fprintf(stderr, "start: %s\n", buf);
5282830Sdjl } else {
5292830Sdjl MKERROR(loglevel, *errpp, rc, strdup(buf),
5302830Sdjl NS_LDAP_MEMORY);
5312830Sdjl }
5322830Sdjl return (rc);
5332830Sdjl }
5342830Sdjl }
5352830Sdjl /*
5362830Sdjl * This is called by ldap_cachemgr to check dns and gssapi prequisites.
5372830Sdjl */
5382830Sdjl int
__ns_ldap_check_all_preq(int foreground,int mode_verbose,int mode_quiet,ns_ldap_self_gssapi_config_t config,ns_ldap_error_t ** errpp)5392830Sdjl __ns_ldap_check_all_preq(int foreground,
5402830Sdjl int mode_verbose,
5412830Sdjl int mode_quiet,
5422830Sdjl ns_ldap_self_gssapi_config_t config,
5432830Sdjl ns_ldap_error_t **errpp) {
5442830Sdjl
5452830Sdjl int rc;
5462830Sdjl
5472830Sdjl if (errpp)
5482830Sdjl *errpp = NULL;
5492830Sdjl else
5502830Sdjl return (NS_LDAP_INVALID_PARAM);
5512830Sdjl
5522830Sdjl if (config == NS_LDAP_SELF_GSSAPI_CONFIG_NONE)
5532830Sdjl /* Don't need to check */
5542830Sdjl return (NS_LDAP_SUCCESS);
5552830Sdjl
5562830Sdjl if ((rc = __ns_ldap_check_dns_preq(foreground,
5572830Sdjl mode_verbose, mode_quiet, NSSWITCH_CONF,
5582830Sdjl config, errpp)) != NS_LDAP_SUCCESS)
5592830Sdjl return (rc);
5602830Sdjl if ((rc = __ns_ldap_check_gssapi_preq(foreground,
5612830Sdjl mode_verbose, mode_quiet, config, errpp)) !=
5622830Sdjl NS_LDAP_SUCCESS)
5632830Sdjl return (rc);
5642830Sdjl
5652830Sdjl return (NS_LDAP_SUCCESS);
5662830Sdjl }
567