/*
*/
/*
* Abstracted contract private interfaces for configuring krb5.conf(4).
*/
#include <ctype.h>
#include <locale.h>
#include "prof_solaris.h"
#include "k5-int.h"
#include "../../util/profile/prof_int.h"
struct profile_string_list {
char **list;
unsigned int num;
unsigned int max;
};
/*
* Initialize the string list abstraction.
*/
{
return ENOMEM;
return 0;
}
/*
* Free any memory left over in the string abstraction, returning the
* built up list in *ret_list if it is non-null.
*/
{
char **cp;
if (list == 0)
return;
if (ret_list) {
return;
} else {
}
}
/*
* Add a string to the list.
*/
{
unsigned int newmax;
if (newlist == 0)
return ENOMEM;
}
if (newstr == 0)
return ENOMEM;
return 0;
}
/*
* key:
* If key is NULL then all entries in the section specified are returned.
* case_ins:
* If set a case insensitive lookup is performed and if found then only one
* entry is returned which only differs by case.
* If unset a case sensitive lookup is performed and all entries matching
* the lookup are returned.
*/
{
return (code);
/* Change loop condition to fix the profile iterator issue */
if (code2 != 0) {
} else
goto cleanup;
goto not_found;
}
if (code2 != 0) {
goto cleanup;
}
}
}
}
}
code = 0;
else
*retvals = ret_values;
return (code);
}
{
return (EINVAL);
}
{
return (EINVAL);
hierarchy[0] = "appdefaults";
/*
* Not fatal if this fails, continue on.
*/
if (code != 0)
return (code);
return (code);
}
{
return (EINVAL);
hierarchy[0] = "logging";
/*
* Not fatal if this fails, continue on.
*/
if (code != 0)
return (code);
if (code != 0)
return (code);
if (code != 0)
return (code);
return (code);
}
/*
* DEPRECATED - use k5_profile_add_libdefaults_entry() instead.
*
* errcode_t k5_profile_set_libdefaults(profile_t profile, char *realm)
*
* where profile was the pointer passed back by k5_profile_init
* where realm is the realm name to be added as the default_realm
*/
{
return (EINVAL);
hierarchy[0] = "libdefaults";
/*
* Not fatal if this fails, continue on.
*/
return (code);
}
{
return (EINVAL);
hierarchy[0] = "realms";
/*
* Not fatal if this fails, continue on.
*/
}
return (code);
}
/*
* errcode_t k5_profile_release(profile_t profile)
*
* where profile was the pointer passed back by k5_profile_init
* Note: used to commit the associated profile to the backing store
* (e.g. file) and free profile memory
* Note: that this function returns an error code which profile_release
* does not. With the error code, the application can determine if they
* need to free the resulting profile information in memory
*/
{
return (EINVAL);
if ((code = profile_close_file(p)) != 0)
return (code);
}
return (0);
}
/*
* void k5_profile_abandon(profile_t profile)
*
* where profile was the pointer passed back by k5_profile_init
* Note: used to free any profile information in memory. Typically can
* be used in conjunction with k5_profile_release upon error
*/
void
{
}
/*
* errcode_t k5_profile_add_domain_mapping(profile_t profile, char *domain,
* char *realm)
*
* where profile was the pointer passed back by k5_profile_init
* where domain is the domain name of the associated realm name
* where realm is the corresponding realm name for the domain
*/
{
return (EINVAL);
hierarchy[0] = "domain_realm";
/*
* Not fatal if relation can't be cleared, continue on.
*/
return (code);
}
/*
* errcode_t k5_profile_remove_domain_mapping(profile_t profile, char *realm)
*
* where profile was the pointer passed back by k5_profile_init
* where realm is the corresponding realm name for the domain
* Note: for the remove function, all matching domain - realm mappings
* will be removed for realm
*/
{
return (EINVAL);
hierarchy[0] = "domain_realm";
if (code != 0)
goto error;
}
}
return (code);
}
/*
* errcode_t k5_profile_get_realm_entry(profile_t profile, char *realm,
* char *name, char ***ret_value)
*
* where profile was the pointer passed back by k5_profile_init
* where realm is the target realm for lookup
* where name is the name in the realm section requested
* where ret_value is a string array of any matching values assigned to name.
* The array is terminated with a NULL pointer.
* Note: if name has not been configured then NULL is returned for ret_value.
*/
char ***ret_value)
{
return (EINVAL);
hierarchy[0] = "realms";
if (code == PROF_NO_RELATION)
code = 0;
return (code);
}
/*
* errcode_t k5_profile_add_realm_entry(profile_t profile, char *realm,
* char *name, char **value)
*
* where profile was the pointer passed back by k5_profile_init
* where realm is the target realm for the name-value pair
* where name is the name in the realm subsection to add
* where value is a string array values to assigned to name. The array is
* terminated with a NULL pointer.
* Note: if the realm subsection does no exist then an error is returned
* Note: if the name already exists the set is overwritten with the values
* passed
*/
char **values)
{
return (EINVAL);
hierarchy[0] = "realms";
/*
* Not fatal if this fails, continue on.
*/
if (code != 0)
return (code);
}
return (0);
}
/*
* DEPRECATED - use k5_profile_get_libdefaults_entry() instead.
*
* errcode_t k5_profile_get_default_realm(profile_t profile, char **realm)
* where profile was the pointer passed back by k5_profile_init
* where realm is the default_realm configured for the system
* Note: if default_realm has not been configured then NULL is returned for
* realm.
*/
{
return (EINVAL);
realm);
if (code == PROF_NO_RELATION)
code = 0;
return (code);
}
/*
* errcode_t k5_profile_get_realms(profile_t profile, char ***realms)
*
* where profile was the pointer passed back by k5_profile_init
* where realms is a string array of realm names currently configured.
* The array is terminated with a NULL pointer.
* Note: if realms have not been configured then NULL is returned for realms.
*/
{
return (EINVAL);
B_FALSE));
}
/*
* errcode_t k5_profile_add_realm(profile_t profile, char *realm,
* char *master, char **kdcs, boolean_t set_change, boolean_t
* default_realm)
*
* where profile was the pointer passed back by k5_profile_init
* where realm is the realm name associated with the configuration
* where master is the server that is assigned to admin_server
* If master is set to NULL, admin_server entry will not be updated.
* where kdcs is a string array of KDCs used to populate the kdc set.
* The array is terminated with a NULL pointer.
* If kdcs is set to NULL, kdc entries will not be updated.
* where set_change, if set, will use the SET_CHANGE protocol for password
* modifications. RPCSEC_GSS is set by default
* where default_realm, if set, will assign the realm to default_realm
* Note: the ordering of kdcs is determined by the server's position in the
* array
*/
{
char **tkdcs;
return (EINVAL);
/*
* Sets the default realm to realm if default_realm flag is set.
*/
if (default_realm == B_TRUE) {
return (code);
}
hierarchy[0] = "realms";
/*
* Not fatal if this fails, therefore return code is not checked.
*/
return (code);
}
/*
* If not set then defaults to undefined, which defaults to RPCSEC_GSS.
*/
if (set_change == B_TRUE) {
if (code != 0)
return (code);
}
return (code);
}
}
if (code != 0)
return (code);
return (code);
}
/*
* errcode_t k5_profile_remove_xrealm_mapping(profile_t profile, char *realm)
*
* where profile was the pointer passed back by k5_profile_init
* where source is the source realm for the capath
* where target is the target realm for the capath
* where inter is the intermediate realm between the source and target
* realms. If the source and target share x-realm keys then this set to "."
* Note: for the remove function, all associated source, target, and
* intermediate entries will be removed matching the realm name
*/
{
return (EINVAL);
hierarchy[0] = "capaths";
/*
* Not fatal if this fails, continue on.
*/
while (code == 0) {
while (code2 == 0) {
&inter);
code3 =
if (code3 != 0) {
goto error;
}
}
}
}
}
}
}
}
}
}
code = 0;
return (code);
}
/*
* errcode_t k5_profile_remove_realm(profile_t profile, char *realm)
*
* where profile was the pointer passed back by k5_profile_init
* where realm is the target realm for removal
* Note: the function removes the matching realm in the realms section,
* the default_realm, relevant domain_realm mappings with the realm name,
* and matching capaths source realm subsection.
*/
{
return (EINVAL);
/*
* Remove the default realm.
*/
hierarchy[0] = "libdefaults";
/*
* We are not returning on missing configuration information given that
* we are performing a best effort on removing as much realm information
* as possible. Regardless of symmetry from adding.
*/
if (code != 0) {
return (code);
}
}
}
hierarchy[0] = "realms";
/*
* Not fatal even if realm wasn't available to remove.
*/
return (0);
}
/*
* errcode_t k5_profile_add_xrealm_mapping(profile_t profile, char *source,
* char *target, char *inter)
*
* where profile was the pointer passed back by k5_profile_init
* where source is the source realm for the capath
* where target is the target realm for the capath
* where inter is the intermediate realm between the source and target
* realms. If the source and target share x-realm keys then this set to "."
* Note: if the section does not exist one will be created
*/
char *inter)
{
return (EINVAL);
hierarchy[0] = "capaths";
/*
* Not fatal if this fails, continue on.
*/
return (code);
}
/*
* errcode_t k5_profile_validate(profile_t profile, char *realm, int *val_err,
* char **val, boolean_t master_required, boolean_t kdc_required)
*
* where profile was the pointer passed back by k5_profile_init
* where realm is the realm name (case sensitive) to be inspected.
* where val_err is a function specific error code of the following values:
* K5_PROFILE_VAL_SUCCESS
* No errors detected in profile
* (val returns realm validated)
* K5_PROFILE_VAL_DEF_REALM_CASE
* default realm only differs in case from the realm specified
* (val returns default realm configured)
* K5_PROFILE_VAL_REALM_CASE
* realm in realms section differs in case from the realm specified
* (val returns realm configured)
* K5_PROFILE_VAL_NO_DEF_IN_REALM
* default realm is not found in realms section
* (val returns realm not found)
* K5_PROFILE_VAL_NO_DEF_REALM
* default realm does not exist
* (val returns realm specified)
* K5_PROFILE_VAL_NULL_REALM
* no realm found in realms section
* (val returns realm specified)
* K5_PROFILE_VAL_NO_DOM_REALM_MAP
* no domain realm mapping entry found from the realm specified
* (val returns realm specified)
* K5_PROFILE_VAL_KDC_NO_REALM
* kdc relation-value does not exist for specified realm
* (val returns realm specified)
* K5_PROFILE_VAL_ADMIN_NO_REALM
* admin_server relation-value does not exist for specified realm
* (val returns realm specified)
* K5_PROFILE_VAL_DOM_REALM_CASE
* the realm name argument differs in case from the realm name argument
* for a domain-realm mapping entry
* K5_PROFILE_VAL_NO_REALM
* realm name specified is not found in realms section
* (val returns the realm specified)
* where val is the associated errant value, associated with val_err. This
* value is returned as is from the profile.
* where master_required is a boolean value to determine whether admin_server
* should be validated.
* where kdc_rqeuired is a boolean value to determine whether kdc entries should
* be validated.
*
* Note: function infers the following:
* 1. all required entries are present
* 2. all relations are defined between default realm, realm, and
* domain - realm mappings
*
* Note: The return value of this function is based on the error code returned
* validation error code set to non-zero if the profile is invalid in any way.
*
* Caution: This function could return false positives on valid
* configurations and should only be used by the CIFS team for
* specific purposes.
*/
{
return (EINVAL);
goto cleanup;
} else
continue;
}
break;
}
goto cleanup;
} else
goto cleanup;
if (found_realm == B_FALSE) {
goto cleanup;
}
/*
* Perform case insensitive lookup first, followed by case
* sensitive search. This allows detection of lower case names
* before an exact match, which would not match if the name was
* in lower case.
*/
goto cleanup;
goto cleanup;
} else
goto cleanup;
} else
goto cleanup;
if (kdc_required == B_TRUE) {
"kdc", &ret_vals);
goto cleanup;
} else
goto cleanup;
}
if (master_required == B_TRUE) {
"admin_server", &ret_vals);
goto cleanup;
} else
goto cleanup;
}
goto cleanup;
}
}
goto cleanup;
} else
goto cleanup;
break;
}
}
goto cleanup;
}
if (default_realm != NULL)
return (code);
}
/*
* errcode_t k5_profile_init(char *filename, profile_t *profile)
*
* where filename is the specified profile location. If filename is NULL
* where profile is pointer passed to caller upon success
* Note: if the file does not exist then one will be created
* Note: the function assumes that the profile file resides in a directory only
* writable by root as the O_NOLINKS mode for open() was removed to avoid a
* EMLINK ("Too many inks") issue with one of its consumers
* Note: if the file does exist then any existing profile information will
* be in profile
* Note: profile_release() should be used by the caller to free profile
*/
{
return (EINVAL);
return (ENOMEM);
return (ENOMEM);
}
} else {
if (ret != 0)
return (ret);
}
/*
* If file does not exist then create said file.
*/
if (fd < 0) {
return (err);
} else
/*
* Specify non-null for specific file (to load any existing profile)
*/
return (code);
}
/*
* k5_profile_validate_get_error_msg(profile_t profile, int err, char *val,
* char **err_msg)
*
* intput arguments:
* where profile was pointer passed back by k5_profile_init
* where err is the val_err returned by the k5_profile_validate function
* where val is the val returned by the k5_profile_validate function
*
* output arguments:
* where err_msg is the returned error message string
*
* Note: Upon success an error string will be passed back by the caller in
* err_msg else an error code is returned and err_msg is not allocated.
*/
char **err_msg)
{
char *m;
return (EINVAL);
switch (err) {
case K5_PROFILE_VAL_SUCCESS:
m = _("No error");
break;
m = _("default_realm should be in upper-case");
break;
m = _("realm in [realms] section should be in upper-case");
break;
m = _("default_realm is not found in [realms] section");
break;
m = _("default_realm doesn't exist in the [libdefaults] section");
break;
m = _("no realms found in the [realms] section");
break;
m = _("missing mapping entry in the [domain_realm] "
"section for the specified realm");
break;
m = _("no kdc entries found for the specified realm");
break;
m = _("no admin_server entry found for the specified realm");
break;
m = _("mapping entry in [domain_realm] section for "
"the specified realm should be in upper-case");
break;
case K5_PROFILE_VAL_NO_REALM:
m = _("specified realm not found in [realms] section");
break;
default:
m = _("unknown error");
break;
}
return (code);
}
/*
* errcode_t k5_profile_get_libdefaults_entry(profile_t profile, char *name,
* char ***ret_value)
*
* where profile was the pointer passed back by k5_profile_init
* where name is the name of the requested relation
* where ret_value is the value assigned to name
* Note: if name has not been configured, ret_value is set to NULL and
* the function returns 0.
*/
char **ret_value)
{
return (EINVAL);
hierarchy[0] = "libdefaults";
if (code == PROF_NO_RELATION)
code = 0;
return (code);
}
/*
* errcode_t k5_profile_add_libdefaults_entry(profile_t profile char *name,
* char **value)
*
* where profile was the pointer passed back by k5_profile_init
* where name is the name of the relation to be set
* where value is the value to be assigned to name.
* Note: if the name already exists, the value is overwritten with the value
* passed
*/
{
return (EINVAL);
hierarchy[0] = "libdefaults";
/*
* Not fatal if this fails, continue on.
*/
return (code);
}
/*
* Solaris Kerberos
* profile_get_options_boolean() and profile_get_options_string() are Solaris
* specific.
*/
char ** section;
{
char ** actual_section;
int i, max_i;
actual_section[i] = section[i];
(char **)&value);
(retval != PROF_NO_SECTION)) {
return (retval);
}
/*
* Any string other than true will turn off the
* option
*/
else
}
}
} else {
}
return (retval);
}
char ** section;
{
char ** actual_section;
int i, max_i;
actual_section[i] = section[i];
(char **)&value);
(retval != PROF_NO_SECTION)) {
return (retval);
}
} else
}
} else {
}
return (retval);
}