Exemple #1
0
static FILE *set_up_log_file(e2fsck_t ctx, const char *key, const char *fn)
{
	FILE *f = NULL;
	struct string s, s1, s2;
	char *s0 = 0, *log_dir = 0, *log_fn = 0;
	int log_dir_wait = 0;

	s.s = s1.s = s2.s = 0;

	profile_get_boolean(ctx->profile, "options", "log_dir_wait", 0, 0,
			    &log_dir_wait);
	if (fn)
		log_fn = string_copy(ctx, fn, 0);
	else
		profile_get_string(ctx->profile, "options", key,
				   0, 0, &log_fn);
	profile_get_string(ctx->profile, "options", "log_dir", 0, 0, &log_dir);

	if (!log_fn || !log_fn[0])
		goto out;

	expand_logfn(ctx, log_fn, &s);
	if ((log_fn[0] == '/') || !log_dir || !log_dir[0])
		s0 = s.s;

	if (log_dir && log_dir[0]) {
		alloc_string(&s1, strlen(log_dir) + strlen(s.s) + 2);
		append_string(&s1, log_dir, 0);
		append_string(&s1, "/", 1);
		append_string(&s1, s.s, 0);
	}

	free(log_dir);
	profile_get_string(ctx->profile, "options", "log_dir_fallback", 0, 0,
			   &log_dir);
	if (log_dir && log_dir[0]) {
		alloc_string(&s2, strlen(log_dir) + strlen(s.s) + 2);
		append_string(&s2, log_dir, 0);
		append_string(&s2, "/", 1);
		append_string(&s2, s.s, 0);
		printf("%s\n", s2.s);
	}

	if (s0)
		f = fopen(s0, "w");
	if (!f && s1.s)
		f = fopen(s1.s, "w");
	if (!f && s2.s)
		f = fopen(s2.s, "w");
	if (!f && log_dir_wait)
		f = save_output(s0, s1.s, s2.s);

out:
	free(s.s);
	free(s1.s);
	free(s2.s);
	free(log_fn);
	free(log_dir);
	return f;
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
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;
}
static void setup_tdb(e2fsck_t ctx, ext2_ino_t num_dirs)
{
    struct dir_info_db	*db = ctx->dir_info;
    unsigned int		threshold;
    errcode_t		retval;
    char			*tdb_dir, uuid[40];
    int			fd, enable;

    profile_get_string(ctx->profile, "scratch_files", "directory", 0, 0,
                       &tdb_dir);
    profile_get_uint(ctx->profile, "scratch_files",
                     "numdirs_threshold", 0, 0, &threshold);
    profile_get_boolean(ctx->profile, "scratch_files",
                        "dirinfo", 0, 1, &enable);

    if (!enable || !tdb_dir || access(tdb_dir, W_OK) ||
            (threshold && num_dirs <= threshold))
        return;

    retval = ext2fs_get_mem(strlen(tdb_dir) + 64, &db->tdb_fn);
    if (retval)
        return;

    uuid_unparse(ctx->fs->super->s_uuid, uuid);
    sprintf(db->tdb_fn, "%s/%s-dirinfo-XXXXXX", tdb_dir, uuid);
    fd = mkstemp(db->tdb_fn);
    db->tdb = tdb_open(db->tdb_fn, 0, TDB_CLEAR_IF_FIRST,
                       O_RDWR | O_CREAT | O_TRUNC, 0600);
    close(fd);
}
Exemple #6
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;
}
Exemple #7
0
/* We don't have non-null defaults in any of our calls, so don't bother with
 * the extra argument. */
static krb5_error_code
prof_get_string_def(krb5_context ctx, const char *conf_section,
                    const char *name, char **out)
{
    krb5_error_code ret;

    ret = profile_get_string(ctx->profile, KDB_MODULE_SECTION, conf_section,
                             name, NULL, out);
    if (ret)
        return attr_read_error(ctx, ret, name);
    if (*out != NULL)
        return 0;
    ret = profile_get_string(ctx->profile, KDB_MODULE_DEF_SECTION, name, NULL,
                             NULL, out);
    if (ret)
        return attr_read_error(ctx, ret, name);
    return 0;
}
Exemple #8
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;
}
Exemple #9
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;
}
/*
 * Find the admin server for the given realm. If the realm is null or
 * the empty string, find the admin server for the default realm.
 * Returns 0 on succsess (KADM5_OK). It is the callers responsibility to
 * free the storage allocated to the admin server, master.
 */
kadm5_ret_t
kadm5_get_master(krb5_context context, const char *realm, char **master)
{
	/* Solaris Kerberos */
	char *def_realm = NULL;

	char *delim;
#ifdef KRB5_DNS_LOOKUP
	struct sockaddr *addrs;
	int naddrs;
	unsigned short dns_portno;
	char dns_host[MAX_DNS_NAMELEN];
	krb5_data dns_realm;
	krb5_error_code dns_ret = 1;
#endif /* KRB5_DNS_LOOKUP */

	if (realm == 0 || *realm == '\0')
		krb5_get_default_realm(context, &def_realm);

	(void) profile_get_string(context->profile, "realms",
	    realm ? realm : def_realm,
	    KADM5_MASTER, 0, master);

	if ((*master != NULL) && ((delim = strchr(*master, ':')) != NULL))
		*delim = '\0';
#ifdef KRB5_DNS_LOOKUP
	if (*master == NULL) {
		/*
		 * Initialize realm info for (possible) DNS lookups.
		 */
		dns_realm.data = strdup(realm ? realm : def_realm);
		dns_realm.length = strlen(realm ? realm : def_realm);
		dns_realm.magic = 0;

		dns_ret = krb5_get_servername(context, &dns_realm,
		    "_kerberos-adm", "_udp",
		    dns_host, &dns_portno);
		if (dns_ret == 0)
			*master = strdup(dns_host);

		if (dns_realm.data)
			free(dns_realm.data);
	}
#endif /* KRB5_DNS_LOOKUP */

	/* Solaris Kerberos */
	if (def_realm != NULL)
		krb5_free_default_realm(context, def_realm);

	return (*master ? KADM5_OK : KADM5_NO_SRV);
}
Exemple #11
0
static void setup_tdb(e2fsck_t ctx, ext2_ino_t num_dirs)
{
    struct dir_info_db	*db = ctx->dir_info;
    unsigned int		threshold;
    errcode_t		retval;
    mode_t			save_umask;
    char			*tdb_dir, uuid[40];
    int			fd, enable;

    profile_get_string(ctx->profile, "scratch_files", "directory", 0, 0,
                       &tdb_dir);
    profile_get_uint(ctx->profile, "scratch_files",
                     "numdirs_threshold", 0, 0, &threshold);
    profile_get_boolean(ctx->profile, "scratch_files",
                        "dirinfo", 0, 1, &enable);

    if (!enable || !tdb_dir || access(tdb_dir, W_OK) ||
            (threshold && num_dirs <= threshold))
        return;

    retval = ext2fs_get_mem(strlen(tdb_dir) + 64, &db->tdb_fn);
    if (retval)
        return;

    uuid_unparse(ctx->fs->super->s_uuid, uuid);
    sprintf(db->tdb_fn, "%s/%s-dirinfo-XXXXXX", tdb_dir, uuid);
    save_umask = umask(077);
    fd = mkstemp(db->tdb_fn);
    umask(save_umask);
    if (fd < 0) {
        db->tdb = NULL;
        return;
    }

    if (num_dirs < 99991)
        num_dirs = 99991; /* largest 5 digit prime */

    db->tdb = tdb_open(db->tdb_fn, num_dirs, TDB_NOLOCK | TDB_NOSYNC,
                       O_RDWR | O_CREAT | O_TRUNC, 0600);
    close(fd);
}
Exemple #12
0
static krb5_error_code
get_tristate(krb5_context ctx, const char *name, const char *third_option,
             int third_option_val, int def_val, int *val_out)
{
    krb5_error_code retval;
    char *str;
    int match;

    retval = profile_get_boolean(ctx->profile, KRB5_CONF_LIBDEFAULTS, name,
                                 NULL, def_val, val_out);
    if (retval != PROF_BAD_BOOLEAN)
        return retval;
    retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS, name,
                                NULL, NULL, &str);
    if (retval)
        return retval;
    match = (strcasecmp(third_option, str) == 0);
    free(str);
    if (!match)
        return EINVAL;
    *val_out = third_option_val;
    return 0;
}
Exemple #13
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;
}
/*
 * Find the kpasswd server for the given realm. If the realm is null or
 * the empty string, find the admin server for the default realm.
 * Returns 0 on succsess (KADM5_OK). It is the callers responsibility to
 * free the storage allocated to the admin server, master.
 */
kadm5_ret_t
kadm5_get_kpasswd(krb5_context context, const char *realm, char **kpasswd)
{
	char *def_realm = NULL;
	char *delim;
#ifdef KRB5_DNS_LOOKUP
	struct sockaddr *addrs;
	int naddrs;
	unsigned short dns_portno;
	char dns_host[MAX_DNS_NAMELEN];
	krb5_data dns_realm;
	krb5_error_code dns_ret = 1, ret;
#endif /* KRB5_DNS_LOOKUP */

	if (realm == 0 || *realm == '\0') {
		ret = krb5_get_default_realm(context, &def_realm);
		if (ret != 0)
			return (ret);
	}

	(void) profile_get_string(context->profile, "realms",
	    realm ? realm : def_realm,
	    KADM5_KPASSWD, 0, kpasswd);

	if ((*kpasswd != NULL) && ((delim = strchr(*kpasswd, ':')) != NULL))
		*delim = '\0';
#ifdef KRB5_DNS_LOOKUP
	if (*kpasswd == NULL) {
		/*
		 * Initialize realm info for (possible) DNS lookups.
		 */
		dns_realm.data = strdup(realm ? realm : def_realm);
		if (dns_realm.data == NULL) {
			if (def_realm != NULL)
				free(def_realm);
			return (ENOMEM);
		}
		dns_realm.length = strlen(realm ? realm : def_realm);
		dns_realm.magic = 0;

		dns_ret = krb5_get_servername(context, &dns_realm,
		    "_kpasswd", "_tcp",
		    dns_host, &dns_portno);
		if (dns_ret == 0) {
			*kpasswd = strdup(dns_host);

			if (*kpasswd == NULL) {
				free(dns_realm.data);
				if (def_realm != NULL)
					free(def_realm);
				return (ENOMEM);
			}
		}

		free(dns_realm.data);
	}
#endif /* KRB5_DNS_LOOKUP */

	if (def_realm != NULL)
		free(def_realm);
	return (*kpasswd ? KADM5_OK : KADM5_NO_SRV);
}
Exemple #15
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);
}
Exemple #16
0
/*
 * krb5_klog_init()	- Initialize logging.
 *
 * This routine parses the syntax described above to specify destinations for
 * com_err(3) or krb5_klog_syslog() messages generated by the caller.
 *
 * Parameters:
 *	kcontext	- Kerberos context.
 *	ename		- Entity name as it is to appear in the profile.
 *	whoami		- Entity name as it is to appear in error output.
 *	do_com_err	- Take over com_err(3) processing.
 *
 * Implicit inputs:
 *	stderr		- This is where STDERR output goes.
 *
 * Implicit outputs:
 *	log_nentries	- Number of log entries, both valid and invalid.
 *	log_control	- List of entries (log_nentries long) which contains
 *			  data for klog_com_err_proc() to use to determine
 *			  where/how to send output.
 */
krb5_error_code
krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do_com_err)
{
    const char	*logging_profent[3];
    const char	*logging_defent[3];
    char	**logging_specs;
    int		i, ngood;
    char	*cp, *cp2;
    char	savec = '\0';
    int		error;
    int		do_openlog, log_facility;
    FILE	*f;
    mode_t      old_umask;

    /* Initialize */
    do_openlog = 0;
    log_facility = 0;

    err_context = kcontext;

    /*
     * Look up [logging]-><ename> in the profile.  If that doesn't
     * succeed, then look for [logging]->default.
     */
    logging_profent[0] = "logging";
    logging_profent[1] = ename;
    logging_profent[2] = (char *) NULL;
    logging_defent[0] = "logging";
    logging_defent[1] = "default";
    logging_defent[2] = (char *) NULL;
    logging_specs = (char **) NULL;
    ngood = 0;
    log_control.log_nentries = 0;
    if (!profile_get_values(kcontext->profile,
			    logging_profent,
			    &logging_specs) ||
	!profile_get_values(kcontext->profile,
			    logging_defent,
			    &logging_specs)) {
	/*
	 * We have a match, so we first count the number of elements
	 */
	for (log_control.log_nentries = 0;
	     logging_specs[log_control.log_nentries];
	     log_control.log_nentries++);

	/*
	 * Now allocate our structure.
	 */
	log_control.log_entries = (struct log_entry *)
	    malloc(log_control.log_nentries * sizeof(struct log_entry));
	if (log_control.log_entries) {
	    /*
	     * Scan through the list.
	     */
	    for (i=0; i<log_control.log_nentries; i++) {
		log_control.log_entries[i].log_type = K_LOG_NONE;
		log_control.log_entries[i].log_2free = logging_specs[i];
		/*
		 * The format is:
		 *	<whitespace><data><whitespace>
		 * so, trim off the leading and trailing whitespace here.
		 */
		for (cp = logging_specs[i]; isspace((int) *cp); cp++);
		for (cp2 = &logging_specs[i][strlen(logging_specs[i])-1];
		     isspace((int) *cp2); cp2--);
		cp2++;
		*cp2 = '\0';
		/*
		 * Is this a file?
		 */
		if (!strncasecmp(cp, "FILE", 4)) {
		    /*
		     * Check for append/overwrite, then open the file.
		     */
		    if (cp[4] == ':' || cp[4] == '=') {
			log_control.log_entries[i].lfu_fopen_mode = 
				(cp[4] == ':') ? "a+F" : "wF";
			old_umask = umask(077);
			f = fopen(&cp[5],
				log_control.log_entries[i].lfu_fopen_mode);
			umask(old_umask);
			if (f) {
                            char rotate_kw[128];

			    log_control.log_entries[i].lfu_filep = f;
			    log_control.log_entries[i].log_type = K_LOG_FILE;
			    log_control.log_entries[i].lfu_fname = &cp[5];
			    log_control.log_entries[i].lfu_rotate_period = 
				K_LOG_DEF_FILE_ROTATE_PERIOD;
			    log_control.log_entries[i].lfu_rotate_versions =
				K_LOG_DEF_FILE_ROTATE_VERSIONS;
			    log_control.log_entries[i].lfu_last_rotated =
				time(0);
				
			/*
			 * Now parse for ename_"rotate" = {
			 *	period = XXX
			 * 	versions = 10
			 * }
			 */
			    if (strlen(ename) + strlen("_rotate") <
				sizeof (rotate_kw)) {

				    char *time;
				    krb5_deltat	dt;
				    int vers;

				    strcpy(rotate_kw, ename);
				    strcat(rotate_kw, "_rotate");

				    if (!profile_get_string(kcontext->profile,
				        "logging", rotate_kw, "period",
					NULL, &time)) {

					if (time != NULL) {
					    if (!krb5_string_to_deltat(time,
						&dt)) {
			log_control.log_entries[i].lfu_rotate_period =
							(time_t) dt;
					    }
					    free(time);
					}
				    }
				
				    if (!profile_get_integer(
					kcontext->profile, "logging",
					rotate_kw, "versions",
					K_LOG_DEF_FILE_ROTATE_VERSIONS,
					&vers)) {
			log_control.log_entries[i].lfu_rotate_versions = vers;
				    }
			
			   }
			} else {
			    fprintf(stderr, gettext("Couldn't open log file %s: %s\n"),
				    &cp[5], error_message(errno));
			    continue;
			}
		    }
		}
#ifdef	HAVE_SYSLOG
		/*
		 * Is this a syslog?
		 */
		else if (!strncasecmp(cp, "SYSLOG", 6)) {
		    error = 0;
		    log_control.log_entries[i].lsu_facility = LOG_AUTH;
		    log_control.log_entries[i].lsu_severity = LOG_ERR;
		    /*
		     * Is there a severify specified?
		     */
		    if (cp[6] == ':') {
			/*
			 * Find the end of the severity.
			 */
			cp2 = strchr(&cp[7], ':');
			if (cp2) {
			    savec = *cp2;
			    *cp2 = '\0';
			    cp2++;
			}

			/*
			 * Match a severity.
			 */
			if (!strcasecmp(&cp[7], "ERR")) {
			    log_control.log_entries[i].lsu_severity = LOG_ERR;
			}
#ifdef	LOG_EMERG
			else if (!strcasecmp(&cp[7], "EMERG")) {
			    log_control.log_entries[i].lsu_severity =
				LOG_EMERG;
			}
#endif	/* LOG_EMERG */
#ifdef	LOG_ALERT
			else if (!strcasecmp(&cp[7], "ALERT")) {
			    log_control.log_entries[i].lsu_severity =
				LOG_ALERT;
			}
#endif	/* LOG_ALERT */
#ifdef	LOG_CRIT
			else if (!strcasecmp(&cp[7], "CRIT")) {
			    log_control.log_entries[i].lsu_severity = LOG_CRIT;
			}
#endif	/* LOG_CRIT */
#ifdef	LOG_WARNING
			else if (!strcasecmp(&cp[7], "WARNING")) {
			    log_control.log_entries[i].lsu_severity =
				LOG_WARNING;
			}
#endif	/* LOG_WARNING */
#ifdef	LOG_NOTICE
			else if (!strcasecmp(&cp[7], "NOTICE")) {
			    log_control.log_entries[i].lsu_severity =
				LOG_NOTICE;
			}
#endif	/* LOG_NOTICE */
#ifdef	LOG_INFO
			else if (!strcasecmp(&cp[7], "INFO")) {
			    log_control.log_entries[i].lsu_severity = LOG_INFO;
			}
#endif	/* LOG_INFO */
#ifdef	LOG_DEBUG
			else if (!strcasecmp(&cp[7], "DEBUG")) {
			    log_control.log_entries[i].lsu_severity =
				LOG_DEBUG;
			}
#endif	/* LOG_DEBUG */
			else
			    error = 1;

			/*
			 * If there is a facility present, then parse that.
			 */
			if (cp2) {
			    if (!strcasecmp(cp2, "AUTH")) {
				log_control.log_entries[i].lsu_facility = LOG_AUTH;
			    }
			    else if (!strcasecmp(cp2, "KERN")) {
				log_control.log_entries[i].lsu_facility = LOG_KERN;
			    }
			    else if (!strcasecmp(cp2, "USER")) {
				log_control.log_entries[i].lsu_facility = LOG_USER;
			    }
			    else if (!strcasecmp(cp2, "MAIL")) {
				log_control.log_entries[i].lsu_facility = LOG_MAIL;
			    }
			    else if (!strcasecmp(cp2, "DAEMON")) {
				log_control.log_entries[i].lsu_facility = LOG_DAEMON;
			    }
			    else if (!strcasecmp(cp2, "LPR")) {
				log_control.log_entries[i].lsu_facility = LOG_LPR;
			    }
			    else if (!strcasecmp(cp2, "NEWS")) {
				log_control.log_entries[i].lsu_facility = LOG_NEWS;
			    }
			    else if (!strcasecmp(cp2, "UUCP")) {
				log_control.log_entries[i].lsu_facility = LOG_UUCP;
			    }
			    else if (!strcasecmp(cp2, "CRON")) {
				log_control.log_entries[i].lsu_facility = LOG_CRON;
			    }
			    else if (!strcasecmp(cp2, "LOCAL0")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL0;
			    }
			    else if (!strcasecmp(cp2, "LOCAL1")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL1;
			    }
			    else if (!strcasecmp(cp2, "LOCAL2")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL2;
			    }
			    else if (!strcasecmp(cp2, "LOCAL3")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL3;
			    }
			    else if (!strcasecmp(cp2, "LOCAL4")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL4;
			    }
			    else if (!strcasecmp(cp2, "LOCAL5")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL5;
			    }
			    else if (!strcasecmp(cp2, "LOCAL6")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL6;
			    }
			    else if (!strcasecmp(cp2, "LOCAL7")) {
				log_control.log_entries[i].lsu_facility = LOG_LOCAL7;
			    }
			    cp2--;
			    *cp2 = savec;
			}
		    }
		    if (!error) {
			log_control.log_entries[i].log_type = K_LOG_SYSLOG;
			do_openlog = 1;
			log_facility = log_control.log_entries[i].lsu_facility;
		    }
		}
#endif	/* HAVE_SYSLOG */
		/*
		 * Is this a standard error specification?
		 */
		else if (!strcasecmp(cp, "STDERR")) {
		    log_control.log_entries[i].lfu_filep =
			fdopen(fileno(stderr), "a+F");
		    if (log_control.log_entries[i].lfu_filep) {
			log_control.log_entries[i].log_type = K_LOG_STDERR;
			log_control.log_entries[i].lfu_fname =
			    "standard error";
		    }
		}
		/*
		 * Is this a specification of the console?
		 */
		else if (!strcasecmp(cp, "CONSOLE")) {
		    log_control.log_entries[i].ldu_filep =
			CONSOLE_OPEN("a+F");
		    if (log_control.log_entries[i].ldu_filep) {
			log_control.log_entries[i].log_type = K_LOG_CONSOLE;
			log_control.log_entries[i].ldu_devname = "console";
		    }
		}
		/*
		 * Is this a specification of a device?
		 */
		else if (!strncasecmp(cp, "DEVICE", 6)) {
		    /*
		     * We handle devices very similarly to files.
		     */
		    if (cp[6] == '=') {
			log_control.log_entries[i].ldu_filep = 
			    DEVICE_OPEN(&cp[7], "wF");
			if (log_control.log_entries[i].ldu_filep) {
			    log_control.log_entries[i].log_type = K_LOG_DEVICE;
			    log_control.log_entries[i].ldu_devname = &cp[7];
			}
		    }
		}
		/*
		 * See if we successfully parsed this specification.
		 */
		if (log_control.log_entries[i].log_type == K_LOG_NONE) {
		    fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_1), whoami, cp);
		    fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_2), whoami);
		}
		else
		    ngood++;
	    }
	}
	/*
	 * If we didn't find anything, then free our lists.
	 */
	if (ngood == 0) {
	    for (i=0; i<log_control.log_nentries; i++)
		free(logging_specs[i]);
	}
	free(logging_specs);
    }
    /*
     * If we didn't find anything, go for the default which is to log to
     * the system log.
     */
    if (ngood == 0) {
	if (log_control.log_entries)
	    free(log_control.log_entries);
	log_control.log_entries = &def_log_entry;
	log_control.log_entries->log_type = K_LOG_SYSLOG;
	log_control.log_entries->log_2free = (krb5_pointer) NULL;
	log_facility = log_control.log_entries->lsu_facility = LOG_AUTH;
	log_control.log_entries->lsu_severity = LOG_ERR;
	do_openlog = 1;
	log_control.log_nentries = 1;
    }
    if (log_control.log_nentries) {
	log_control.log_whoami = (char *) malloc(strlen(whoami)+1);
	if (log_control.log_whoami)
	    strcpy(log_control.log_whoami, whoami);

	log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN + 1);
	if (log_control.log_hostname) {
	    gethostname(log_control.log_hostname, MAXHOSTNAMELEN);
	    log_control.log_hostname[MAXHOSTNAMELEN] = '\0';
	}
#ifdef	HAVE_OPENLOG
	if (do_openlog) {
	    openlog(whoami, LOG_NDELAY|LOG_PID, log_facility);
	    log_control.log_opened = 1;
	}
#endif /* HAVE_OPENLOG */
	if (do_com_err)
	    (void) set_com_err_hook(klog_com_err_proc);
    }
    return((log_control.log_nentries) ? 0 : ENOENT);
}
Exemple #17
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;
}
Exemple #18
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);
}
Exemple #19
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;
}
Exemple #20
0
/*
 * This function will create a krbcontainer and realm on the LDAP Server, with
 * the specified attributes.
 */
krb5_error_code
krb5_ldap_create(krb5_context context, char *conf_section, char **db_args)
{
    krb5_error_code status = 0;
    char  **t_ptr = db_args;
    krb5_ldap_realm_params *rparams = NULL;
    kdb5_dal_handle *dal_handle = NULL;
    krb5_ldap_context *ldap_context=NULL;
    krb5_boolean realm_obj_created = FALSE;
    krb5_boolean krbcontainer_obj_created = FALSE;
    krb5_ldap_krbcontainer_params kparams = {0};
    int srv_cnt = 0;
    int mask = 0;

    /* Clear the global error string */
    krb5_clear_error_message(context);

    ldap_context = malloc(sizeof(krb5_ldap_context));
    if (ldap_context == NULL) {
        status = ENOMEM;
        goto cleanup;
    }
    memset(ldap_context, 0, sizeof(*ldap_context));

    ldap_context->kcontext = context;

    /* populate ldap_context with ldap specific options */
    while (t_ptr && *t_ptr) {
        char *opt = NULL, *val = NULL;

        if ((status = krb5_ldap_get_db_opt(*t_ptr, &opt, &val)) != 0) {
            goto cleanup;
        }
        if (opt && !strcmp(opt, "binddn")) {
            if (ldap_context->bind_dn) {
                free (opt);
                free (val);
                status = EINVAL;
                krb5_set_error_message (context, status, "'binddn' missing");
                goto cleanup;
            }
            if (val == NULL) {
                status = EINVAL;
                krb5_set_error_message (context, status, "'binddn' value missing");
                free(opt);
                goto cleanup;
            }
            ldap_context->bind_dn = strdup(val);
            if (ldap_context->bind_dn == NULL) {
                free (opt);
                free (val);
                status = ENOMEM;
                goto cleanup;
            }
        } else if (opt && !strcmp(opt, "nconns")) {
            if (ldap_context->max_server_conns) {
                free (opt);
                free (val);
                status = EINVAL;
                krb5_set_error_message (context, status, "'nconns' missing");
                goto cleanup;
            }
            if (val == NULL) {
                status = EINVAL;
                krb5_set_error_message (context, status, "'nconns' value missing");
                free(opt);
                goto cleanup;
            }
            ldap_context->max_server_conns = atoi(val) ? atoi(val) : DEFAULT_CONNS_PER_SERVER;
        } else if (opt && !strcmp(opt, "bindpwd")) {
            if (ldap_context->bind_pwd) {
                free (opt);
                free (val);
                status = EINVAL;
                krb5_set_error_message (context, status, "'bindpwd' missing");
                goto cleanup;
            }
            if (val == NULL) {
                status = EINVAL;
                krb5_set_error_message (context, status, "'bindpwd' value missing");
                free(opt);
                goto cleanup;
            }
            ldap_context->bind_pwd = strdup(val);
            if (ldap_context->bind_pwd == NULL) {
                free (opt);
                free (val);
                status = ENOMEM;
                goto cleanup;
            }
        } else if (opt && !strcmp(opt, "host")) {
            if (val == NULL) {
                status = EINVAL;
                krb5_set_error_message (context, status, "'host' value missing");
                free(opt);
                goto cleanup;
            }
            if (ldap_context->server_info_list == NULL)
                ldap_context->server_info_list =
                    (krb5_ldap_server_info **) calloc(SERV_COUNT+1, sizeof(krb5_ldap_server_info *));

            if (ldap_context->server_info_list == NULL) {
                free (opt);
                free (val);
                status = ENOMEM;
                goto cleanup;
            }

            ldap_context->server_info_list[srv_cnt] =
                (krb5_ldap_server_info *) calloc(1, sizeof(krb5_ldap_server_info));
            if (ldap_context->server_info_list[srv_cnt] == NULL) {
                free (opt);
                free (val);
                status = ENOMEM;
                goto cleanup;
            }

            ldap_context->server_info_list[srv_cnt]->server_status = NOTSET;

            ldap_context->server_info_list[srv_cnt]->server_name = strdup(val);
            if (ldap_context->server_info_list[srv_cnt]->server_name == NULL) {
                free (opt);
                free (val);
                status = ENOMEM;
                goto cleanup;
            }

            srv_cnt++;
        } else {
            /* ignore hash argument. Might have been passed from create */
            status = EINVAL;
            if (opt && !strcmp(opt, "temporary")) {
                /*
                 * temporary is passed in when kdb5_util load without -update is done.
                 * This is unsupported by the LDAP plugin.
                 */
                krb5_set_error_message(context, status,
                                       _("creation of LDAP entries aborted, "
                                         "plugin requires -update argument"));
            } else {
                krb5_set_error_message(context, status,
                                       _("unknown option \'%s\'"),
                                       opt?opt:val);
            }
            free(opt);
            free(val);
            goto cleanup;
        }

        free(opt);
        free(val);
        t_ptr++;
    }

    dal_handle = context->dal_handle;
    dal_handle->db_context = (kdb5_dal_handle *) ldap_context;

    status = krb5_ldap_read_server_params(context, conf_section, KRB5_KDB_SRV_TYPE_ADMIN);
    if (status) {
        dal_handle->db_context = NULL;
        prepend_err_str (context, "Error reading LDAP server params: ", status, status);
        goto cleanup;
    }
    status = krb5_ldap_db_init(context, ldap_context);
    if (status) {
        goto cleanup;
    }

    /* read the kerberos container */
    if ((status = krb5_ldap_read_krbcontainer_params(context,
                                                     &(ldap_context->krbcontainer))) == KRB5_KDB_NOENTRY) {

        /* Read the kerberos container location from configuration file */
        if (ldap_context->conf_section) {
            if ((status = profile_get_string(context->profile,
                                             KDB_MODULE_SECTION, ldap_context->conf_section,
                                             KRB5_CONF_LDAP_KERBEROS_CONTAINER_DN, NULL,
                                             &kparams.DN)) != 0) {
                goto cleanup;
            }
        }
        if (kparams.DN == NULL) {
            if ((status = profile_get_string(context->profile,
                                             KDB_MODULE_DEF_SECTION,
                                             KRB5_CONF_LDAP_KERBEROS_CONTAINER_DN, NULL,
                                             NULL, &kparams.DN)) != 0) {
                goto cleanup;
            }
        }

        /* create the kerberos container */
        status = krb5_ldap_create_krbcontainer(context,
                                               ((kparams.DN != NULL) ? &kparams : NULL));
        if (status)
            goto cleanup;

        krbcontainer_obj_created = TRUE;

        status = krb5_ldap_read_krbcontainer_params(context,
                                                    &(ldap_context->krbcontainer));
        if (status)
            goto cleanup;

    } else if (status) {
        goto cleanup;
    }

    rparams = (krb5_ldap_realm_params *) malloc(sizeof(krb5_ldap_realm_params));
    if (rparams == NULL) {
        status = ENOMEM;
        goto cleanup;
    }
    memset(rparams, 0, sizeof(*rparams));
    rparams->realm_name = strdup(context->default_realm);
    if (rparams->realm_name == NULL) {
        status = ENOMEM;
        goto cleanup;
    }

    if ((status = krb5_ldap_create_realm(context, rparams, mask)))
        goto cleanup;

    /* We just created the Realm container. Here starts our transaction tracking */
    realm_obj_created = TRUE;

    /* verify realm object */
    if ((status = krb5_ldap_read_realm_params(context,
                                              rparams->realm_name,
                                              &(ldap_context->lrparams),
                                              &mask)))
        goto cleanup;

cleanup:

    /* If the krbcontainer/realm creation is not complete, do the roll-back here */
    if ((krbcontainer_obj_created) && (!realm_obj_created)) {
        int rc;
        rc = krb5_ldap_delete_krbcontainer(context,
                                           ((kparams.DN != NULL) ? &kparams : NULL));
        krb5_set_error_message(context, rc,
                               _("could not complete roll-back, error "
                                 "deleting Kerberos Container"));
    }

    /* should call krb5_ldap_free_krbcontainer_params() but can't */
    if (kparams.DN != NULL)
        krb5_xfree(kparams.DN);

    if (rparams)
        krb5_ldap_free_realm_params(rparams);

    return(status);
}
Exemple #21
0
/*
 * This function will create a krbcontainer and realm on the LDAP Server, with
 * the specified attributes.
 */
krb5_error_code
krb5_ldap_create (krb5_context context, char *conf_section, char **db_args)
{
    krb5_error_code status = 0;
    char  **t_ptr = db_args;
    krb5_ldap_realm_params *rparams = NULL;
    kdb5_dal_handle *dal_handle = NULL;
    krb5_ldap_context *ldap_context=NULL;
    krb5_boolean realm_obj_created = FALSE;
    krb5_boolean krbcontainer_obj_created = FALSE;
    krb5_ldap_krbcontainer_params kparams = {0};
    int srv_cnt = 0;
    int mask = 0;
#ifdef HAVE_EDIRECTORY
    int i = 0, rightsmask = 0;
#endif

    /* Clear the global error string */
    krb5_clear_error_message(context);

    ldap_context = malloc(sizeof(krb5_ldap_context));
    if (ldap_context == NULL) {
	status = ENOMEM;
	goto cleanup;
    }
    memset(ldap_context, 0, sizeof(*ldap_context));

    ldap_context->kcontext = context;

    /* populate ldap_context with ldap specific options */
    while (t_ptr && *t_ptr) {
	char *opt = NULL, *val = NULL;

	if ((status = krb5_ldap_get_db_opt(*t_ptr, &opt, &val)) != 0) {
	    goto cleanup;
	}
	if (opt && !strcmp(opt, "binddn")) {
	    if (ldap_context->bind_dn) {
		free (opt);
		free (val);
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'binddn' missing"));
		goto cleanup;
	    }
	    if (val == NULL) {
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'binddn' value missing"));
		free(opt);
		goto cleanup;
	    }
	    ldap_context->bind_dn = strdup(val);
	    if (ldap_context->bind_dn == NULL) {
		free (opt);
		free (val);
		status = ENOMEM;
		goto cleanup;
	    }
	} else if (opt && !strcmp(opt, "nconns")) {
	    if (ldap_context->max_server_conns) {
		free (opt);
		free (val);
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'nconns' missing"));
		goto cleanup;
	    }
	    if (val == NULL) {
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'nconns' value missing"));
		free(opt);
		goto cleanup;
	    }
	    ldap_context->max_server_conns = atoi(val) ? atoi(val) : DEFAULT_CONNS_PER_SERVER;
	} else if (opt && !strcmp(opt, "bindpwd")) {
	    if (ldap_context->bind_pwd) {
		free (opt);
		free (val);
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'bindpwd' missing"));
		goto cleanup;
	    }
	    if (val == NULL) {
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'bindpwd' value missing"));
		free(opt);
		goto cleanup;
	    }
	    ldap_context->bind_pwd = strdup(val);
	    if (ldap_context->bind_pwd == NULL) {
		free (opt);
		free (val);
		status = ENOMEM;
		goto cleanup;
	    }
	} else if (opt && !strcmp(opt, "host")) {
	    if (val == NULL) {
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'host' value missing"));
		free(opt);
		goto cleanup;
	    }
	    if (ldap_context->server_info_list == NULL)
		ldap_context->server_info_list =
		    (krb5_ldap_server_info **) calloc(SERV_COUNT+1, sizeof(krb5_ldap_server_info *));

	    if (ldap_context->server_info_list == NULL) {
		free (opt);
		free (val);
		status = ENOMEM;
		goto cleanup;
	    }

	    ldap_context->server_info_list[srv_cnt] =
		(krb5_ldap_server_info *) calloc(1, sizeof(krb5_ldap_server_info));
	    if (ldap_context->server_info_list[srv_cnt] == NULL) {
		free (opt);
		free (val);
		status = ENOMEM;
		goto cleanup;
	    }

	    ldap_context->server_info_list[srv_cnt]->server_status = NOTSET;

	    ldap_context->server_info_list[srv_cnt]->server_name = strdup(val);
	    if (ldap_context->server_info_list[srv_cnt]->server_name == NULL) {
		free (opt);
		free (val);
		status = ENOMEM;
		goto cleanup;
	    }

	    srv_cnt++;
#ifdef HAVE_EDIRECTORY
	} else if (opt && !strcmp(opt, "cert")) {
	    if (val == NULL) {
		status = EINVAL;
		krb5_set_error_message (context, status, gettext("'cert' value missing"));
		free(opt);
		goto cleanup;
	    }

	    if (ldap_context->root_certificate_file == NULL) {
		ldap_context->root_certificate_file = strdup(val);
		if (ldap_context->root_certificate_file == NULL) {
		    free (opt);
		    free (val);
		    status = ENOMEM;
		    goto cleanup;
		}
	    } else {
		void *tmp=NULL;
		char *oldstr = NULL;
		unsigned int len=0;

		oldstr = strdup(ldap_context->root_certificate_file);
		if (oldstr == NULL) {
		    free (opt);
		    free (val);
		    status = ENOMEM;
		    goto cleanup;
		}

		tmp = ldap_context->root_certificate_file;
		len = strlen(ldap_context->root_certificate_file) + 2 + strlen(val);
		ldap_context->root_certificate_file = realloc(ldap_context->root_certificate_file,
							      len);
		if (ldap_context->root_certificate_file == NULL) {
		    free (tmp);
		    free (opt);
		    free (val);
		    status = ENOMEM;
		    goto cleanup;
		}
		memset(ldap_context->root_certificate_file, 0, len);
		sprintf(ldap_context->root_certificate_file,"%s %s", oldstr, val);
		free (oldstr);
	    }
#endif
	} else {
	/* ignore hash argument. Might have been passed from create */
	    status = EINVAL;
	    if (opt && !strcmp(opt, "temporary")) {
		/* 
		 * temporary is passed in when kdb5_util load without -update is done.
		 * This is unsupported by the LDAP plugin.
		 */
		krb5_set_error_message (context, status,
		    gettext("creation of LDAP entries aborted, plugin requires -update argument"));
	    } else {
		krb5_set_error_message (context, status, gettext("unknown option \'%s\'"),
					opt?opt:val);
	    }
	    free(opt);
	    free(val);
	    goto cleanup;
	}

	free(opt);
	free(val);
	t_ptr++;
    }

    dal_handle = (kdb5_dal_handle *) context->db_context;
    dal_handle->db_context = (kdb5_dal_handle *) ldap_context;

    status = krb5_ldap_read_server_params(context, conf_section, KRB5_KDB_SRV_TYPE_ADMIN);
    if (status) {
	dal_handle->db_context = NULL;
	prepend_err_str (context, gettext("Error reading LDAP server params: "), status, status);
	goto cleanup;
    }
    status = krb5_ldap_db_init(context, ldap_context);
    if (status) {
	goto cleanup;
    }

    /* read the kerberos container */
    if ((status = krb5_ldap_read_krbcontainer_params(context,
			    &(ldap_context->krbcontainer))) == KRB5_KDB_NOENTRY) {

	/* Read the kerberos container location from configuration file */
	if (ldap_context->conf_section) {
	    if ((status = profile_get_string(context->profile,
					   KDB_MODULE_SECTION, ldap_context->conf_section,
					   "ldap_kerberos_container_dn", NULL,
					   &kparams.DN)) != 0) {
		goto cleanup;
	    }
	}
	if (kparams.DN == NULL) {
	    if ((status = profile_get_string(context->profile,
					   KDB_MODULE_DEF_SECTION,
					   "ldap_kerberos_container_dn", NULL,
					   NULL, &kparams.DN)) != 0) {
		goto cleanup;
	    }
	}

	/* create the kerberos container */
	status = krb5_ldap_create_krbcontainer(context,
					       ((kparams.DN != NULL) ? &kparams : NULL));
	if (status)
	    goto cleanup;

	krbcontainer_obj_created = TRUE;

	status = krb5_ldap_read_krbcontainer_params(context,
						    &(ldap_context->krbcontainer));
	if (status) {
	    krb5_set_error_message(context, status, gettext("while reading kerberos container information"));
	    goto cleanup;
	}

    } else if (status) {
	krb5_set_error_message(context, status, gettext("while reading kerberos container information"));
	goto cleanup;
    }

    rparams = (krb5_ldap_realm_params *) malloc(sizeof(krb5_ldap_realm_params));
    if (rparams == NULL) {
	status = ENOMEM;
	goto cleanup;
    }
    memset(rparams, 0, sizeof(*rparams));
    rparams->realm_name = strdup(context->default_realm);
    if (rparams->realm_name == NULL) {
	status = ENOMEM;
	goto cleanup;
    }

    if ((status = krb5_ldap_create_realm(context, rparams, mask))) {
	krb5_set_error_message(context, status, gettext("while creating realm object entry"));
	goto cleanup;
    }

    /* We just created the Realm container. Here starts our transaction tracking */
    realm_obj_created = TRUE;

    /* verify realm object */
    if ((status = krb5_ldap_read_realm_params(context,
					      rparams->realm_name,
					      &(ldap_context->lrparams),
					      &mask))) {
	krb5_set_error_message(context, status, gettext("while reading realm object entry"));
	goto cleanup;
    }

#ifdef HAVE_EDIRECTORY
    if ((mask & LDAP_REALM_KDCSERVERS) || (mask & LDAP_REALM_ADMINSERVERS) ||
	(mask & LDAP_REALM_PASSWDSERVERS)) {

	rightsmask =0;
	rightsmask |= LDAP_REALM_RIGHTS;
	rightsmask |= LDAP_SUBTREE_RIGHTS;
	if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
	    for (i=0; (rparams->kdcservers[i] != NULL); i++) {
		if ((status=krb5_ldap_add_service_rights(context,
				     LDAP_KDC_SERVICE, rparams->kdcservers[i],
				     rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
		    goto cleanup;
		}
	    }
	}

	rightsmask = 0;
	rightsmask |= LDAP_REALM_RIGHTS;
	rightsmask |= LDAP_SUBTREE_RIGHTS;
	if ((rparams != NULL) && (rparams->adminservers != NULL)) {
	    for (i=0; (rparams->adminservers[i] != NULL); i++) {
		if ((status=krb5_ldap_add_service_rights(context,
				     LDAP_ADMIN_SERVICE, rparams->adminservers[i],
				     rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
		    goto cleanup;
		}
	    }
	}

	rightsmask = 0;
	rightsmask |= LDAP_REALM_RIGHTS;
	rightsmask |= LDAP_SUBTREE_RIGHTS;
	if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
	    for (i=0; (rparams->passwdservers[i] != NULL); i++) {
		if ((status=krb5_ldap_add_service_rights(context,
				     LDAP_PASSWD_SERVICE, rparams->passwdservers[i],
				     rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
		    goto cleanup;
		}
	    }
	}
    }
#endif

cleanup:

    /* If the krbcontainer/realm creation is not complete, do the roll-back here */
    if ((krbcontainer_obj_created) && (!realm_obj_created)) {
	int rc;
	rc = krb5_ldap_delete_krbcontainer(context,
		    ((kparams.DN != NULL) ? &kparams : NULL));
	krb5_set_error_message(context, rc,
	    gettext("could not complete roll-back, error deleting Kerberos Container"));
    }

    /* should call krb5_ldap_free_krbcontainer_params() but can't */
    if (kparams.DN != NULL)
	krb5_xfree(kparams.DN);

    if (rparams)
	krb5_ldap_free_realm_params(rparams);

    return(status);
}
Exemple #22
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;
}
Exemple #23
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;
}
Exemple #24
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;
}
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;
}
Exemple #26
0
krb5_error_code
krb5_ldap_read_krbcontainer_params(krb5_context context,
                                   krb5_ldap_krbcontainer_params **cparamp)

{
    krb5_error_code                 st=0, tempst=0;
    LDAP                            *ld=NULL;
    LDAPMessage                     *result=NULL, *ent=NULL;
    krb5_ldap_krbcontainer_params   *cparams=NULL;
    kdb5_dal_handle                 *dal_handle=NULL;
    krb5_ldap_context               *ldap_context=NULL;
    krb5_ldap_server_handle         *ldap_server_handle=NULL;

    SETUP_CONTEXT();
    GET_HANDLE();

    cparams =(krb5_ldap_krbcontainer_params *) malloc(sizeof(krb5_ldap_krbcontainer_params));
    CHECK_NULL(cparams);
    memset(cparams, 0, sizeof(krb5_ldap_krbcontainer_params));

    /* read kerberos containter location from [dbmodules] section of krb5.conf file */
    if (ldap_context->conf_section) {
        if ((st=profile_get_string(context->profile, KDB_MODULE_SECTION, ldap_context->conf_section,
                                   KRB5_CONF_LDAP_KERBEROS_CONTAINER_DN, NULL,
                                   &cparams->DN)) != 0) {
            krb5_set_error_message(context, st,
                                   _("Error reading kerberos container "
                                     "location from krb5.conf"));
            goto cleanup;
        }
    }

    /* read kerberos containter location from [dbdefaults] section of krb5.conf file */
    if (cparams->DN == NULL) {
        if ((st=profile_get_string(context->profile, KDB_MODULE_DEF_SECTION,
                                   KRB5_CONF_LDAP_KERBEROS_CONTAINER_DN, NULL,
                                   NULL, &cparams->DN)) != 0) {
            krb5_set_error_message(context, st,
                                   _("Error reading kerberos container "
                                     "location from krb5.conf"));
            goto cleanup;
        }
    }

    if (cparams->DN == NULL) {
        st = KRB5_KDB_SERVER_INTERNAL_ERR;
        krb5_set_error_message(context, st,
                               _("Kerberos container location not specified"));
        goto cleanup;
    }

    /* NOTE: krbmaxtktlife, krbmaxrenewableage ... present on Kerberos Container is
     * not read
     */
    LDAP_SEARCH_1(cparams->DN, LDAP_SCOPE_BASE, "(objectclass=krbContainer)", policyrefattribute, IGNORE_STATUS);
    if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_OBJECT) {
        st = set_ldap_error(context, st, OP_SEARCH);
        goto cleanup;
    }

    if (st == LDAP_NO_SUCH_OBJECT) {
        st = KRB5_KDB_NOENTRY;
        goto cleanup;
    }

    if ((ent = ldap_first_entry(ld, result))) {
        if ((st=krb5_ldap_get_string(ld, ent, "krbticketpolicyreference",
                                     &(cparams->policyreference), NULL)) != 0)
            goto cleanup;
    }
    ldap_msgfree(result);

    if (cparams->policyreference != NULL) {
        LDAP_SEARCH_1(cparams->policyreference, LDAP_SCOPE_BASE, NULL, policy_attributes, IGNORE_STATUS);
        if (st != LDAP_SUCCESS && st!= LDAP_NO_SUCH_OBJECT) {
            st = set_ldap_error(context, st, OP_SEARCH);
            goto cleanup;
        }
        st = LDAP_SUCCESS; /* reset the return status in case it is LDAP_NO_SUCH_OBJECT */

        ent=ldap_first_entry(ld, result);
        if (ent != NULL) {
            krb5_ldap_get_value(ld, ent, "krbmaxtktlife", &(cparams->max_life));
            krb5_ldap_get_value(ld, ent, "krbmaxrenewableage", &(cparams->max_renewable_life));
            krb5_ldap_get_value(ld, ent, "krbticketflags", &(cparams->tktflags));
        }
        ldap_msgfree(result);
    }
    *cparamp=cparams;

cleanup:
    if (st != 0) {
        krb5_ldap_free_krbcontainer_params(cparams);
        *cparamp=NULL;
    }
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
    return st;
}
Exemple #27
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);
}