Beispiel #1
0
static char *
kdb_get_conf_section(krb5_context kcontext)
{
    krb5_error_code status = 0;
    char   *result = NULL;
    char   *value = NULL;

    if (kcontext->default_realm == NULL)
	return NULL;
    /* The profile has to have been initialized.  If the profile was
       not initialized, expect nothing less than a crash.  */
    status = profile_get_string(kcontext->profile,
				/* realms */
				KDB_REALM_SECTION,
				kcontext->default_realm,
				/* under the realm name, database_module */
				KDB_MODULE_POINTER,
				/* default value is the realm name itself */
				kcontext->default_realm,
				&value);

    if (status) {
	/* some problem */
	result = strdup(kcontext->default_realm);
	/* let NULL be handled by the caller */
    } else {
	result = strdup(value);
	/* free profile string */
	profile_release_string(value);
    }

    return result;
}
Beispiel #2
0
const char * KRB5_CALLCONV
krb5_cc_default_name(krb5_context context)
{
    krb5_os_context os_ctx;
    char *profstr, *envstr;

    if (!context || context->magic != KV5M_CONTEXT)
        return NULL;

    os_ctx = &context->os_context;
    if (os_ctx->default_ccname != NULL)
        return os_ctx->default_ccname;

    /* Try the environment variable first. */
    envstr = getenv(KRB5_ENV_CCNAME);
    if (envstr != NULL) {
        os_ctx->default_ccname = strdup(envstr);
        return os_ctx->default_ccname;
    }

    if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                           KRB5_CONF_DEFAULT_CCACHE_NAME, NULL, NULL,
                           &profstr) == 0 && profstr != NULL) {
        (void)k5_expand_path_tokens(context, profstr, &os_ctx->default_ccname);
        profile_release_string(profstr);
        return os_ctx->default_ccname;
    }

    /* Fall back on the default ccache name for the OS. */
    get_from_os(context);
    return os_ctx->default_ccname;
}
Beispiel #3
0
/*
 * Find the k5login filename for luser, either in the user's homedir or in a
 * configured directory under the username.
 */
static krb5_error_code
get_k5login_filename(krb5_context context, const char *luser,
                     const char *homedir, char **filename_out)
{
    krb5_error_code ret;
    char *dir, *filename;

    *filename_out = NULL;
    ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                             KRB5_CONF_K5LOGIN_DIRECTORY, NULL, NULL, &dir);
    if (ret != 0)
        return ret;

    if (dir == NULL) {
        /* Look in the user's homedir. */
        if (asprintf(&filename, "%s/.k5login", homedir) < 0)
            return ENOMEM;
    } else {
        /* Look in the configured directory. */
        if (asprintf(&filename, "%s/%s", dir, luser) < 0)
            ret = ENOMEM;
        profile_release_string(dir);
        if (ret)
            return ret;
    }
    *filename_out = filename;
    return 0;
}
Beispiel #4
0
static char *
kdb_get_library_name(krb5_context kcontext)
{
    krb5_error_code status = 0;
    char   *result = NULL;
    char   *value = NULL;
    char   *lib = NULL;

    status = profile_get_string(kcontext->profile,
				/* realms */
				KDB_REALM_SECTION,
				kcontext->default_realm,
				/* under the realm name, database_module */
				KDB_MODULE_POINTER,
				/* default value is the realm name itself */
				kcontext->default_realm,
				&value);
    if (status) {
	goto clean_n_exit;
    }

#define DB2_NAME "db2"
    /* we got the module section. Get the library name from the module */
    status = profile_get_string(kcontext->profile, KDB_MODULE_SECTION, value,
				KDB_LIB_POINTER,
				/* default to db2 */
				DB2_NAME,
				&lib);

    if (status) {
	goto clean_n_exit;
    }

    result = strdup(lib);
  clean_n_exit:
    if (value) {
	/* free profile string */
	profile_release_string(value);
    }

    if (lib) {
	/* free profile string */
	profile_release_string(lib);
    }
    return result;
}
Beispiel #5
0
static int
maybe_use_reverse_dns (krb5_context context, int defalt)
{
    krb5_error_code code;
    char * value = NULL;
    int use_rdns = 0;

    code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                              KRB5_CONF_RDNS, 0, 0, &value);
    if (code)
        return defalt;

    if (value == 0)
        return defalt;

    use_rdns = _krb5_conf_boolean(value);
    profile_release_string(value);
    return use_rdns;
}
Beispiel #6
0
static int
maybe_use_dns (krb5_context context, const char *name, int defalt)
{
    krb5_error_code code;
    char * value = NULL;
    int use_dns = 0;

    code = profile_get_string(context->profile, "libdefaults",
                              name, 0, 0, &value);
    if (value == 0 && code == 0)
	code = profile_get_string(context->profile, "libdefaults",
				  "dns_fallback", 0, 0, &value);
    if (code)
        return defalt;

    if (value == 0)
	return defalt;

    use_dns = _krb5_conf_boolean(value);
    profile_release_string(value);
    return use_dns;
}
Beispiel #7
0
static int
maybe_use_dns (krb5_context context, const char *name, int defalt)
{
    krb5_error_code code;
    char * value = NULL;
    int use_dns = 0;

    code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                              name, 0, 0, &value);
    if (value == 0 && code == 0) {
        code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                                  KRB5_CONF_DNS_FALLBACK, 0, 0, &value);
    }
    if (code)
        return defalt;

    if (value == 0)
        return defalt;

    use_dns = _krb5_conf_boolean(value);
    profile_release_string(value);
    return use_dns;
}
Beispiel #8
0
/*
 * Set *etypes_ptr to a zero-terminated list of enctypes.  ctx_list
 * (containing application-specified enctypes) is used if non-NULL;
 * otherwise the libdefaults profile string specified by profkey is
 * used.  default_list is the default enctype list to be used while
 * parsing profile strings, and is also used if the profile string is
 * not set.
 */
static krb5_error_code
get_profile_etype_list(krb5_context context, krb5_enctype **etypes_ptr,
                       char *profkey, krb5_enctype *ctx_list,
                       krb5_enctype *default_list)
{
    krb5_enctype *etypes;
    krb5_error_code code;
    char *profstr;

    *etypes_ptr = NULL;

    if (ctx_list) {
        /* Use application defaults. */
        code = k5_copy_etypes(ctx_list, &etypes);
        if (code)
            return code;
    } else {
        /* Parse profile setting, or "DEFAULT" if not specified. */
        code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                                  profkey, NULL, "DEFAULT", &profstr);
        if (code)
            return code;
        code = krb5int_parse_enctype_list(context, profkey, profstr,
                                          default_list, &etypes);
        profile_release_string(profstr);
        if (code)
            return code;
    }

    if (etypes[0] == 0) {
        free(etypes);
        return KRB5_CONFIG_ETYPE_NOSUPP;
    }

    *etypes_ptr = etypes;
    return 0;
}
Beispiel #9
0
/*
 * This function reads the parameters from the krb5.conf file. The
 * parameters read here are DAL-LDAP specific attributes. Some of
 * these are ldap_server ....
 */
krb5_error_code
krb5_ldap_read_server_params(krb5_context context, char *conf_section,
                             int srv_type)
{
    char *servers, *save_ptr, *item;
    const char *delims = "\t\n\f\v\r ,", *name;
    krb5_error_code ret = 0;
    kdb5_dal_handle *dal_handle = context->dal_handle;
    krb5_ldap_context *ldap_context = dal_handle->db_context;

    /* copy the conf_section into ldap_context for later use */
    if (conf_section != NULL) {
        ldap_context->conf_section = strdup(conf_section);
        if (ldap_context->conf_section == NULL)
            return ENOMEM;
    }

    /* This mutex is used in the LDAP connection pool. */
    if (k5_mutex_init(&(ldap_context->hndl_lock)) != 0)
        return KRB5_KDB_SERVER_INTERNAL_ERR;

    /* Read the maximum number of LDAP connections per server. */
    if (ldap_context->max_server_conns == 0) {
        ret = prof_get_integer_def(context, conf_section,
                                   KRB5_CONF_LDAP_CONNS_PER_SERVER,
                                   DEFAULT_CONNS_PER_SERVER,
                                   &ldap_context->max_server_conns);
        if (ret)
            return ret;
    }

    if (ldap_context->max_server_conns < 2) {
        k5_setmsg(context, EINVAL,
                  _("Minimum connections required per server is 2"));
        return EINVAL;
    }

    /* Read the DN used to connect to the LDAP server. */
    if (ldap_context->bind_dn == NULL) {
        name = choose_var(srv_type, KRB5_CONF_LDAP_KDC_DN,
                          KRB5_CONF_LDAP_KADMIND_DN);
        ret = prof_get_string_def(context, conf_section, name,
                                  &ldap_context->bind_dn);
        if (ret)
            return ret;
    }

    /* Read the filename containing stashed DN passwords. */
    if (ldap_context->service_password_file == NULL) {
        ret = prof_get_string_def(context, conf_section,
                                  KRB5_CONF_LDAP_SERVICE_PASSWORD_FILE,
                                  &ldap_context->service_password_file);
        if (ret)
            return ret;
    }

    if (ldap_context->sasl_mech == NULL) {
        name = choose_var(srv_type, KRB5_CONF_LDAP_KDC_SASL_MECH,
                          KRB5_CONF_LDAP_KADMIND_SASL_MECH);
        ret = prof_get_string_def(context, conf_section, name,
                                  &ldap_context->sasl_mech);
        if (ret)
            return ret;
    }

    if (ldap_context->sasl_authcid == NULL) {
        name = choose_var(srv_type, KRB5_CONF_LDAP_KDC_SASL_AUTHCID,
                          KRB5_CONF_LDAP_KADMIND_SASL_AUTHCID);
        ret = prof_get_string_def(context, conf_section, name,
                                  &ldap_context->sasl_authcid);
        if (ret)
            return ret;
    }

    if (ldap_context->sasl_authzid == NULL) {
        name = choose_var(srv_type, KRB5_CONF_LDAP_KDC_SASL_AUTHZID,
                          KRB5_CONF_LDAP_KADMIND_SASL_AUTHZID);
        ret = prof_get_string_def(context, conf_section, name,
                                  &ldap_context->sasl_authzid);
        if (ret)
            return ret;
    }

    if (ldap_context->sasl_realm == NULL) {
        name = choose_var(srv_type, KRB5_CONF_LDAP_KDC_SASL_REALM,
                          KRB5_CONF_LDAP_KADMIND_SASL_REALM);
        ret = prof_get_string_def(context, conf_section, name,
                                  &ldap_context->sasl_realm);
        if (ret)
            return ret;
    }

    /* Read the LDAP server URL list. */
    if (ldap_context->server_info_list == NULL) {
        ret = profile_get_string(context->profile, KDB_MODULE_SECTION,
                                 conf_section, KRB5_CONF_LDAP_SERVERS, NULL,
                                 &servers);
        if (ret)
            return attr_read_error(context, ret, KRB5_CONF_LDAP_SERVERS);

        if (servers == NULL) {
            ret = add_server_entry(context, "ldapi://");
            if (ret)
                return ret;
        } else {
            item = strtok_r(servers, delims, &save_ptr);
            while (item != NULL) {
                ret = add_server_entry(context, item);
                if (ret) {
                    profile_release_string(servers);
                    return ret;
                }
                item = strtok_r(NULL, delims, &save_ptr);
            }
            profile_release_string(servers);
        }
    }

    ret = prof_get_boolean_def(context, conf_section,
                               KRB5_CONF_DISABLE_LAST_SUCCESS, FALSE,
                               &ldap_context->disable_last_success);
    if (ret)
        return ret;

    return prof_get_boolean_def(context, conf_section,
                                KRB5_CONF_DISABLE_LOCKOUT, FALSE,
                                &ldap_context->disable_lockout);
}
Beispiel #10
0
/* Using db_args and the profile, initialize the configurable parameters of the
 * DB context inside context. */
static krb5_error_code
configure_context(krb5_context context, char *conf_section, char **db_args)
{
    krb5_error_code status;
    krb5_db2_context *db_ctx;
    char **t_ptr, *opt = NULL, *val = NULL, *pval = NULL;
    profile_t profile = KRB5_DB_GET_PROFILE(context);
    int bval;

    status = k5db2_init_context(context);
    if (status != 0)
        return status;
    db_ctx = context->dal_handle->db_context;

    for (t_ptr = db_args; t_ptr && *t_ptr; t_ptr++) {
        free(opt);
        free(val);
        status = krb5_db2_get_db_opt(*t_ptr, &opt, &val);
        if (opt && !strcmp(opt, "dbname")) {
            db_ctx->db_name = strdup(val);
            if (db_ctx->db_name == NULL) {
                status = ENOMEM;
                goto cleanup;
            }
        }
        else if (!opt && !strcmp(val, "temporary")) {
            db_ctx->tempdb = 1;
        } else if (!opt && !strcmp(val, "merge_nra")) {
            ;
        } else if (opt && !strcmp(opt, "hash")) {
            db_ctx->hashfirst = TRUE;
        } else {
            status = EINVAL;
            krb5_set_error_message(context, status,
                                   "Unsupported argument \"%s\" for db2",
                                   opt ? opt : val);
            goto cleanup;
        }
    }

    if (db_ctx->db_name == NULL) {
        /* Check for database_name in the db_module section. */
        status = profile_get_string(profile, KDB_MODULE_SECTION, conf_section,
                                    KDB_DB2_DATABASE_NAME, NULL, &pval);
        if (status == 0 && pval == NULL) {
            /* For compatibility, check for database_name in the realm. */
            status = profile_get_string(profile, KDB_REALM_SECTION,
                                        KRB5_DB_GET_REALM(context),
                                        KDB_DB2_DATABASE_NAME,
                                        DEFAULT_KDB_FILE, &pval);
        }
        if (status != 0)
            goto cleanup;
        db_ctx->db_name = strdup(pval);
    }

    status = profile_get_boolean(profile, KDB_MODULE_SECTION, conf_section,
                                 KRB5_CONF_DISABLE_LAST_SUCCESS, FALSE, &bval);
    if (status != 0)
        goto cleanup;
    db_ctx->disable_last_success = bval;

    status = profile_get_boolean(profile, KDB_MODULE_SECTION, conf_section,
                                 KRB5_CONF_DISABLE_LOCKOUT, FALSE, &bval);
    if (status != 0)
        goto cleanup;
    db_ctx->disable_lockout = bval;

cleanup:
    free(opt);
    free(val);
    profile_release_string(pval);
    return status;
}
Beispiel #11
0
krb5_error_code KRB5_CALLCONV
krb5_425_conv_principal(krb5_context context, const char *name,
			const char *instance, const char *realm,
			krb5_principal *princ)
{
     const struct krb_convert *p;
     char buf[256];		/* V4 instances are limited to 40 characters */
     krb5_error_code retval;
     char *domain, *cp;
     char **full_name = 0;
     const char *names[5], *names2[2];
     void*	iterator = NULL;
     char** v4realms = NULL;
     char* realm_name = NULL;
     char* dummy_value = NULL;
     
     /* First, convert the realm, since the v4 realm is not necessarily the same as the v5 realm
        To do that, iterate over all the realms in the config file, looking for a matching 
        v4_realm line */
     names2 [0] = "realms";
     names2 [1] = NULL;
     retval = profile_iterator_create (context -> profile, names2, PROFILE_ITER_LIST_SECTION | PROFILE_ITER_SECTIONS_ONLY, &iterator);
     while (retval == 0) {
     	retval = profile_iterator (&iterator, &realm_name, &dummy_value);
     	if ((retval == 0) && (realm_name != NULL)) {
     		names [0] = "realms";
     		names [1] = realm_name;
     		names [2] = "v4_realm";
     		names [3] = NULL;

     		retval = profile_get_values (context -> profile, names, &v4realms);
     		if ((retval == 0) && (v4realms != NULL) && (v4realms [0] != NULL) && (strcmp (v4realms [0], realm) == 0)) {
     			realm = realm_name;
     			break;
     		} else if (retval == PROF_NO_RELATION) {
     			/* If it's not found, just keep going */
     			retval = 0;
     		}
     	} else if ((retval == 0) && (realm_name == NULL)) {
     		break;
     	}
	if (v4realms != NULL) {
	        profile_free_list(v4realms);
		v4realms = NULL;
	}
     	if (realm_name != NULL) {
     		profile_release_string (realm_name);
     		realm_name = NULL;
     	}
     	if (dummy_value != NULL) {
     		profile_release_string (dummy_value);
     		dummy_value = NULL;
     	}
     }
     
     if (instance) {
	  if (instance[0] == '\0') {
	       instance = 0;
	       goto not_service;
	  }
	  p = sconv_list;
	  while (1) {
	       if (!p->v4_str)
		    goto not_service;
	       if (!strcmp(p->v4_str, name))
		    break;
	       p++;
	  }
	  name = p->v5_str;
	  if ((p->flags & DO_REALM_CONVERSION) && !strchr(instance, '.')) {
	      names[0] = "realms";
	      names[1] = realm;
	      names[2] = "v4_instance_convert";
	      names[3] = instance;
	      names[4] = 0;
	      retval = profile_get_values(context->profile, names, &full_name);
	      if (retval == 0 && full_name && full_name[0]) {
		  instance = full_name[0];
	      } else {
		  strncpy(buf, instance, sizeof(buf));
		  buf[sizeof(buf) - 1] = '\0';
		  retval = krb5_get_realm_domain(context, realm, &domain);
		  if (retval)
		      return retval;
		  if (domain) {
		      for (cp = domain; *cp; cp++)
			  if (isupper((unsigned char) (*cp)))
			      *cp = tolower((unsigned char) *cp);
		      strncat(buf, ".", sizeof(buf) - 1 - strlen(buf));
		      strncat(buf, domain, sizeof(buf) - 1 - strlen(buf));
		      krb5_xfree(domain);
		  }
		  instance = buf;
	      }
	  }
     }
     
not_service:
     retval = krb5_build_principal(context, princ, strlen(realm), realm, name,
				   instance, NULL);
     if (iterator) profile_iterator_free (&iterator);
     if (full_name) profile_free_list(full_name);
     if (v4realms) profile_free_list(v4realms);
     if (realm_name) profile_release_string (realm_name);
     if (dummy_value) profile_release_string (dummy_value);
     return retval;
}
static krb5_error_code
get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr,
		       unsigned int ctx_count, krb5_enctype *ctx_list)
{
    krb5_enctype *old_ktypes = NULL;

    if (ctx_count) {
	/* application-set defaults */
	if ((old_ktypes = 
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) *
				    (ctx_count + 1)))) {
	    (void) memcpy(old_ktypes, ctx_list,
		sizeof(krb5_enctype) * ctx_count);
	    old_ktypes[ctx_count] = 0;
	} else {
	    return ENOMEM;
	}
    } else {
        /*
	   XXX - For now, we only support libdefaults
	   Perhaps this should be extended to allow for per-host / per-realm
	   session key types.
	 */

	char *retval = NULL;
	char *sp, *ep;
	int j, checked_enctypes, count;
	krb5_error_code code;

	code = profile_get_string(context->profile, "libdefaults", profstr,
				  NULL, DEFAULT_ETYPE_LIST, &retval);
	if (code)
	    return code;

	if (!retval)  /* SUNW14resync - just in case */
            return PROF_EINVAL;  /* XXX */

	count = 0;
	sp = retval;
	while (*sp) {
	    for (ep = sp; *ep && (*ep != ',') && !isspace((int) (*ep)); ep++)
		;
	    if (*ep) {
		*ep++ = '\0';
		while (isspace((int) (*ep)) || *ep == ',')
		    *ep++ = '\0';
	    }
	    count++;
	    sp = ep;
	}
	
	if ((old_ktypes =
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
	    (krb5_enctype *) NULL)
	    return ENOMEM;
	
	sp = retval;
	j = checked_enctypes = 0;
	/*CONSTCOND*/
	while (TRUE) {
	    checked_enctypes++;
	    if (krb5_string_to_enctype(sp, &old_ktypes[j]))
		old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN;

	    /*
	     * If 'null' has been specified as a tkt_enctype in
	     * krb5.conf, we need to assign an ENCTYPE_UNKNOWN
	     * value to the corresponding old_ktypes[j] entry.
	     */
	    if (old_ktypes[j] == (unsigned int)ENCTYPE_NULL)
		old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN;

	    /* Only include known/valid enctypes in the final list */
	    if (old_ktypes[j] != ENCTYPE_UNKNOWN) {
		j++;
	    }
	    /* If we checked all the enctypes, we are done */
	    if (checked_enctypes == count) {
		break;
	    }

	    /* skip to next token */
	    while (*sp) sp++;
	    while (! *sp) sp++;
	}

	old_ktypes[j] = (krb5_enctype) 0;
	profile_release_string(retval);
    }

    if (old_ktypes[0] == 0) {
	free (old_ktypes);
	*ktypes = 0;
	return KRB5_CONFIG_ETYPE_NOSUPP;
    }

    *ktypes = old_ktypes;
    return 0;
}
Beispiel #13
0
static krb5_error_code
get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr,
		       unsigned int ctx_count, krb5_enctype *ctx_list)
{
    krb5_enctype *old_ktypes;

    if (ctx_count) {
	/* application-set defaults */
	if ((old_ktypes = 
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) *
				    (ctx_count + 1)))) {
	    memcpy(old_ktypes, ctx_list, sizeof(krb5_enctype) * ctx_count);
	    old_ktypes[ctx_count] = 0;
	} else {
	    return ENOMEM;
	}
    } else {
        /*
	   XXX - For now, we only support libdefaults
	   Perhaps this should be extended to allow for per-host / per-realm
	   session key types.
	 */

	char *retval;
	char *sp, *ep;
	int i, j, count;
	krb5_error_code code;

	code = profile_get_string(context->profile, "libdefaults", profstr,
				  NULL, DEFAULT_ETYPE_LIST, &retval);
	if (code)
	    return code;

	count = 0;
	sp = retval;
	while (*sp) {
	    for (ep = sp; *ep && (*ep != ',') && !isspace((int) (*ep)); ep++)
		;
	    if (*ep) {
		*ep++ = '\0';
		while (isspace((int) (*ep)) || *ep == ',')
		    *ep++ = '\0';
	    }
	    count++;
	    sp = ep;
	}
	
	if ((old_ktypes =
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
	    (krb5_enctype *) NULL) {
	    profile_release_string(retval);
	    return ENOMEM;
	}
	
	sp = retval;
	j = 0;
	i = 1;
	while (1) {
	    if (! krb5_string_to_enctype(sp, &old_ktypes[j]))
		j++;

	    if (i++ >= count)
		break;

	    /* skip to next token */
	    while (*sp) sp++;
	    while (! *sp) sp++;
	}

	old_ktypes[j] = (krb5_enctype) 0;
	profile_release_string(retval);
    }

    if (old_ktypes[0] == 0) {
	free (old_ktypes);
	*ktypes = 0;
	return KRB5_CONFIG_ETYPE_NOSUPP;
    }

    *ktypes = old_ktypes;
    return 0;
}
Beispiel #14
0
krb5_error_code KRB5_CALLCONV
krb5_get_host_realm(krb5_context context, const char *host, char ***realmsp)
{
    char **retrealms;
    char *realm, *cp, *temp_realm;
    krb5_error_code retval;
    char local_host[MAXDNAME+1];

#ifdef DEBUG_REFERRALS
    printf("get_host_realm(host:%s) called\n",host);
#endif

    retval = krb5int_clean_hostname(context, host, local_host, sizeof local_host);
    if (retval)
        return retval;

    /*
       Search for the best match for the host or domain.
       Example: Given a host a.b.c.d, try to match on:
         1) A.B.C.D
	 2) .B.C.D
	 3) B.C.D
	 4) .C.D
	 5) C.D
	 6) .D
	 7) D
     */

    cp = local_host;
#ifdef DEBUG_REFERRALS
    printf("  local_host: %s\n",local_host);
#endif
    realm = (char *)NULL;
    temp_realm = 0;
    while (cp) {
#ifdef DEBUG_REFERRALS
        printf("  trying to look up %s in the domain_realm map\n",cp);
#endif
	retval = profile_get_string(context->profile, KRB5_CONF_DOMAIN_REALM, cp,
				    0, (char *)NULL, &temp_realm);
	if (retval)
	    return retval;
	if (temp_realm != (char *)NULL)
	    break;	/* Match found */

	/* Setup for another test */
	if (*cp == '.') {
	    cp++;
	} else {
	    cp = strchr(cp, '.');
	}
    }
#ifdef DEBUG_REFERRALS
    printf("  done searching the domain_realm map\n");
#endif
    if (temp_realm) {
#ifdef DEBUG_REFERRALS
    printf("  temp_realm is %s\n",temp_realm);
#endif
        realm = strdup(temp_realm);
        if (!realm) {
            profile_release_string(temp_realm);
            return ENOMEM;
        }
        profile_release_string(temp_realm);
    }

    if (realm == (char *)NULL) {
        if (!(cp = strdup(KRB5_REFERRAL_REALM)))
	    return ENOMEM;
	realm = cp;
    }
    
    if (!(retrealms = (char **)calloc(2, sizeof(*retrealms)))) {
	if (realm != (char *)NULL)
	    free(realm);
	return ENOMEM;
    }

    retrealms[0] = realm;
    retrealms[1] = 0;
    
    *realmsp = retrealms;
    return 0;
}
Beispiel #15
0
krb5_error_code KRB5_CALLCONV
krb5_get_default_realm(krb5_context context, char **lrealm)
{
    char *realm = 0;
    char *cp;
    char localhost[MAX_DNS_NAMELEN+1];
    krb5_error_code retval;

    (void) memset(localhost, 0, sizeof(localhost));

    if (!context || (context->magic != KV5M_CONTEXT)) 
	    return KV5M_CONTEXT;

    /*
     * Solaris Kerberos: (illumos)
     * Another way to provide the default realm.
     */
    if (!context->default_realm) {
	if ((realm = getenv("KRB5_DEFAULT_REALM")) != NULL) {
	    context->default_realm = strdup(realm);
	    if (context->default_realm == NULL)
		return ENOMEM;
	}
    }

    if (!context->default_realm) {
        context->default_realm = 0;
        if (context->profile != 0) {
            retval = profile_get_string(context->profile, "libdefaults",
                                        "default_realm", 0, 0,
                                        &realm);

            if (!retval && realm) {
                context->default_realm = malloc(strlen(realm) + 1);
                if (!context->default_realm) {
                    profile_release_string(realm);
                    return ENOMEM;
                }
                strcpy(context->default_realm, realm);
                profile_release_string(realm);
            }
        }
        if (context->default_realm == 0) {
#ifdef KRB5_DNS_LOOKUP
            if (_krb5_use_dns_realm(context)) {
		/*
		 * Since this didn't appear in our config file, try looking
		 * it up via DNS.  Look for a TXT records of the form:
		 *
		 * _kerberos.<localhost>
		 * _kerberos.<domainname>
		 * _kerberos.<searchlist>
		 *
		 */
		char * p;
		krb5int_get_fq_local_hostname (localhost, sizeof(localhost));

		if ( localhost[0] ) {
		    p = localhost;
		    do {
			retval = krb5_try_realm_txt_rr("_kerberos", p, 
						       &context->default_realm);
			p = strchr(p,'.');
			if (p)
			    p++;
		    } while (retval && p && p[0]);

		    if (retval)
			retval = krb5_try_realm_txt_rr("_kerberos", "", 
						       &context->default_realm);
		} else {
		    retval = krb5_try_realm_txt_rr("_kerberos", "", 
						   &context->default_realm);
		}
		if (retval) {
		    return(KRB5_CONFIG_NODEFREALM);
		}
            } else
#endif /* KRB5_DNS_LOOKUP */
            if (getenv("MS_INTEROP") == NULL) {

	/*
	 * Solaris Kerberos:
	 * Try to find a realm based on one of the local IP addresses.
	 * Don't do this for AD, which often does _not_ support any
	 * DNS reverse lookup, making these queries take forever.
	 */
	(void) krb5int_foreach_localaddr(context,
	    krb5int_address_get_realm, 0, 0);

	/*
	 * Solaris Kerberos:
	 * As a final fallback try to find a realm based on the resolver search
	 * list
	 */
	if (context->default_realm == 0) {
		struct __res_state res;
		int i;

		(void) memset(&res, 0, sizeof (res));

		if (res_ninit(&res) == 0) {
			for (i = 0; res.dnsrch[i]; i++) {
				krb5int_domain_get_realm(context,
				    res.dnsrch[i], &context->default_realm); 

				if (context->default_realm != 0)
					break;
			}
		res_ndestroy(&res);
		}
	}

	}
	}
	}

    if (context->default_realm == 0)
	return(KRB5_CONFIG_NODEFREALM);
    if (context->default_realm[0] == 0) {
        free (context->default_realm);
        context->default_realm = 0;
        return KRB5_CONFIG_NODEFREALM;
    }

    realm = context->default_realm;
    
    /*LINTED*/
    if (!(*lrealm = cp = malloc((unsigned int) strlen(realm) + 1)))
        return ENOMEM;
    strcpy(cp, realm);
    return(0);
}
Beispiel #16
0
krb5_error_code KRB5_CALLCONV
krb5_init_context_profile(profile_t profile, krb5_flags flags,
                          krb5_context *context_out)
{
    krb5_context ctx = 0;
    krb5_error_code retval;
    struct {
        krb5_timestamp now;
        krb5_int32 now_usec;
        long pid;
    } seed_data;
    krb5_data seed;
    int tmp;
    char *plugin_dir = NULL;

    /* Verify some assumptions.  If the assumptions hold and the
       compiler is optimizing, this should result in no code being
       executed.  If we're guessing "unsigned long long" instead
       of using uint64_t, the possibility does exist that we're
       wrong.  */
    {
        uint64_t i64;
        assert(sizeof(i64) == 8);
        i64 = 0, i64--, i64 >>= 62;
        assert(i64 == 3);
        i64 = 1, i64 <<= 31, i64 <<= 31, i64 <<= 1;
        assert(i64 != 0);
        i64 <<= 1;
        assert(i64 == 0);
    }

    retval = krb5int_initialize_library();
    if (retval)
        return retval;

#if (defined(_WIN32))
    /*
     * Load the krbcc32.dll if necessary.  We do this here so that
     * we know to use API: later on during initialization.
     * The context being NULL is ok.
     */
    krb5_win_ccdll_load(ctx);

    /*
     * krb5_vercheck() is defined in win_glue.c, and this is
     * where we handle the timebomb and version server checks.
     */
    retval = krb5_vercheck();
    if (retval)
        return retval;
#endif

    *context_out = NULL;

    ctx = calloc(1, sizeof(struct _krb5_context));
    if (!ctx)
        return ENOMEM;
    ctx->magic = KV5M_CONTEXT;

    ctx->profile_secure = (flags & KRB5_INIT_CONTEXT_SECURE) != 0;

    retval = k5_os_init_context(ctx, profile, flags);
    if (retval)
        goto cleanup;

    ctx->trace_callback = NULL;
#ifndef DISABLE_TRACING
    if (!ctx->profile_secure)
        k5_init_trace(ctx);
#endif

    retval = get_boolean(ctx, KRB5_CONF_ALLOW_WEAK_CRYPTO, 0, &tmp);
    if (retval)
        goto cleanup;
    ctx->allow_weak_crypto = tmp;

    retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp);
    if (retval)
        goto cleanup;
    ctx->ignore_acceptor_hostname = tmp;

    retval = get_tristate(ctx, KRB5_CONF_DNS_CANONICALIZE_HOSTNAME, "fallback",
                          CANONHOST_FALLBACK, 1, &tmp);
    if (retval)
        goto cleanup;
    ctx->dns_canonicalize_hostname = tmp;

    /* initialize the prng (not well, but passable) */
    if ((retval = krb5_c_random_os_entropy( ctx, 0, NULL)) !=0)
        goto cleanup;
    if ((retval = krb5_crypto_us_timeofday(&seed_data.now, &seed_data.now_usec)))
        goto cleanup;
    seed_data.pid = getpid ();
    seed.length = sizeof(seed_data);
    seed.data = (char *) &seed_data;
    if ((retval = krb5_c_random_add_entropy(ctx, KRB5_C_RANDSOURCE_TIMING, &seed)))
        goto cleanup;

    ctx->default_realm = 0;
    get_integer(ctx, KRB5_CONF_CLOCKSKEW, DEFAULT_CLOCKSKEW, &tmp);
    ctx->clockskew = tmp;

    /* DCE 1.1 and below only support CKSUMTYPE_RSA_MD4 (2)  */
    /* DCE add kdc_req_checksum_type = 2 to krb5.conf */
    get_integer(ctx, KRB5_CONF_KDC_REQ_CHECKSUM_TYPE, CKSUMTYPE_RSA_MD5,
                &tmp);
    ctx->kdc_req_sumtype = tmp;

    get_integer(ctx, KRB5_CONF_AP_REQ_CHECKSUM_TYPE, 0, &tmp);
    ctx->default_ap_req_sumtype = tmp;

    get_integer(ctx, KRB5_CONF_SAFE_CHECKSUM_TYPE, CKSUMTYPE_RSA_MD5_DES,
                &tmp);
    ctx->default_safe_sumtype = tmp;

    get_integer(ctx, KRB5_CONF_KDC_DEFAULT_OPTIONS, KDC_OPT_RENEWABLE_OK,
                &tmp);
    ctx->kdc_default_options = tmp;
#define DEFAULT_KDC_TIMESYNC 1
    get_integer(ctx, KRB5_CONF_KDC_TIMESYNC, DEFAULT_KDC_TIMESYNC, &tmp);
    ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;

    retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS,
                                KRB5_CONF_PLUGIN_BASE_DIR, 0,
                                DEFAULT_PLUGIN_BASE_DIR, &plugin_dir);
    if (!retval)
        retval = k5_expand_path_tokens(ctx, plugin_dir, &ctx->plugin_base_dir);
    if (retval) {
        TRACE_PROFILE_ERR(ctx, KRB5_CONF_PLUGIN_BASE_DIR,
                          KRB5_CONF_LIBDEFAULTS, retval);
        goto cleanup;
    }

    /*
     * We use a default file credentials cache of 3.  See
     * lib/krb5/krb/ccache/file/fcc.h for a description of the
     * credentials cache types.
     *
     * Note: DCE 1.0.3a only supports a cache type of 1
     *      DCE 1.1 supports a cache type of 2.
     */
#define DEFAULT_CCACHE_TYPE 4
    get_integer(ctx, KRB5_CONF_CCACHE_TYPE, DEFAULT_CCACHE_TYPE, &tmp);
    ctx->fcc_default_format = tmp + 0x0500;
    ctx->prompt_types = 0;
    ctx->use_conf_ktypes = 0;
    ctx->udp_pref_limit = -1;

    /* It's OK if this fails */
    (void)profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS,
                             KRB5_CONF_ERR_FMT, NULL, NULL, &ctx->err_fmt);
    *context_out = ctx;
    ctx = NULL;

cleanup:
    profile_release_string(plugin_dir);
    krb5_free_context(ctx);
    return retval;
}
Beispiel #17
0
krb5_error_code KRB5_CALLCONV
krb5_524_conv_principal(krb5_context context, krb5_const_principal princ,
			char *name, char *inst, char *realm)
{
     const struct krb_convert *p;
     const krb5_data *compo;
     char *c, *tmp_realm, *tmp_prealm;
     unsigned int tmp_realm_len;
     int retval; 

     *name = *inst = '\0';
     switch (krb5_princ_size(context, princ)) {
     case 2:
	  /* Check if this principal is listed in the table */
	  compo = krb5_princ_component(context, princ, 0);
	  p = sconv_list;
	  while (p->v4_str) {
	       if (p->len == compo->length
		   && memcmp(p->v5_str, compo->data, compo->length) == 0) {
		   /*
		    * It is, so set the new name now, and chop off
		    * instance's domain name if requested.
		    */
		   if (strlcpy(name, p->v4_str, ANAME_SZ) >= ANAME_SZ)
		       return KRB5_INVALID_PRINCIPAL;
		   if (p->flags & DO_REALM_CONVERSION) {
		       compo = krb5_princ_component(context, princ, 1);
		       c = strnchr(compo->data, '.', compo->length);
		       if (!c || (c - compo->data) >= INST_SZ - 1)
			   return KRB5_INVALID_PRINCIPAL;
		       memcpy(inst, compo->data, (size_t) (c - compo->data));
		       inst[c - compo->data] = '\0';
		   }
		   break;
	       }
	       p++;
	  }
	  /* If inst isn't set, the service isn't listed in the table, */
	  /* so just copy it. */
	  if (*inst == '\0') {
	       compo = krb5_princ_component(context, princ, 1);
	       if (compo->length >= INST_SZ - 1)
		    return KRB5_INVALID_PRINCIPAL;
	       memcpy(inst, compo->data, compo->length);
	       inst[compo->length] = '\0';
	  }
	  /* fall through */
     case 1:
	  /* name may have been set above; otherwise, just copy it */
	  if (*name == '\0') {
	       compo = krb5_princ_component(context, princ, 0);
	       if (compo->length >= ANAME_SZ)
		    return KRB5_INVALID_PRINCIPAL;
	       memcpy(name, compo->data, compo->length);
	       name[compo->length] = '\0';
	  }
	  break;
     default:
	  return KRB5_INVALID_PRINCIPAL;
     }

     compo = krb5_princ_realm(context, princ);

     tmp_prealm = malloc(compo->length + 1);
     if (tmp_prealm == NULL)
	 return ENOMEM;
     strncpy(tmp_prealm, compo->data, compo->length);
     tmp_prealm[compo->length] = '\0';

     /* Ask for v4_realm corresponding to 
	krb5 principal realm from krb5.conf realms stanza */

     if (context->profile == 0)
       return KRB5_CONFIG_CANTOPEN;
     retval = profile_get_string(context->profile, "realms",
				 tmp_prealm, "v4_realm", 0,
				 &tmp_realm);
     free(tmp_prealm);
     if (retval) { 
	 return retval;
     } else {
	 if (tmp_realm == 0) {
	     if (compo->length > REALM_SZ - 1)
		 return KRB5_INVALID_PRINCIPAL;
	     strncpy(realm, compo->data, compo->length);
	     realm[compo->length] = '\0';
	 } else {
	     tmp_realm_len =  strlen(tmp_realm);
	     if (tmp_realm_len > REALM_SZ - 1)
		 return KRB5_INVALID_PRINCIPAL;
	     strncpy(realm, tmp_realm, tmp_realm_len);
	     realm[tmp_realm_len] = '\0';
	     profile_release_string(tmp_realm);
	 }
     }
     return 0;
}
Beispiel #18
0
krb5_error_code KRB5_CALLCONV
krb5_get_default_realm(krb5_context context, char **lrealm)
{
    char *realm = 0;
    krb5_error_code retval;

    if (!context || (context->magic != KV5M_CONTEXT))
        return KV5M_CONTEXT;

    if (!context->default_realm) {
        /*
         * XXX should try to figure out a reasonable default based
         * on the host's DNS domain.
         */
        context->default_realm = 0;
        if (context->profile != 0) {
            retval = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                                        KRB5_CONF_DEFAULT_REALM, 0, 0,
                                        &realm);

            if (!retval && realm) {
                context->default_realm = strdup(realm);
                if (!context->default_realm) {
                    profile_release_string(realm);
                    return ENOMEM;
                }
                profile_release_string(realm);
            }
        }
#ifndef KRB5_DNS_LOOKUP
        else
            return KRB5_CONFIG_CANTOPEN;
#else /* KRB5_DNS_LOOKUP */
        if (context->default_realm == 0) {
            int use_dns =  _krb5_use_dns_realm(context);
            if ( use_dns ) {
                /*
                 * Since this didn't appear in our config file, try looking
                 * it up via DNS.  Look for a TXT records of the form:
                 *
                 * _kerberos.<localhost>
                 * _kerberos.<domainname>
                 * _kerberos.<searchlist>
                 *
                 */
                char localhost[MAX_DNS_NAMELEN+1];
                char * p;

                krb5int_get_fq_local_hostname (localhost, sizeof(localhost));

                if ( localhost[0] ) {
                    p = localhost;
                    do {
                        retval = krb5_try_realm_txt_rr("_kerberos", p,
                                                       &context->default_realm);
                        p = strchr(p,'.');
                        if (p)
                            p++;
                    } while (retval && p && p[0]);

                    if (retval)
                        retval = krb5_try_realm_txt_rr("_kerberos", "",
                                                       &context->default_realm);
                } else {
                    retval = krb5_try_realm_txt_rr("_kerberos", "",
                                                   &context->default_realm);
                }
                if (retval) {
                    return(KRB5_CONFIG_NODEFREALM);
                }
            }
        }
#endif /* KRB5_DNS_LOOKUP */
    }

    if (context->default_realm == 0)
        return(KRB5_CONFIG_NODEFREALM);
    if (context->default_realm[0] == 0) {
        free (context->default_realm);
        context->default_realm = 0;
        return KRB5_CONFIG_NODEFREALM;
    }

    realm = context->default_realm;

    if (!(*lrealm = strdup(realm)))
        return ENOMEM;
    return(0);
}