/*
SSSD
Kerberos Provider Common Functions
Authors:
Sumit Bose <sbose@redhat.com>
Copyright (C) 2008-2009 Red Hat
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <netdb.h>
#include <signal.h>
#include <ctype.h>
#include "providers/krb5/krb5_common.h"
#include "providers/krb5/krb5_opts.h"
#include "providers/krb5/krb5_utils.h"
#ifdef HAVE_KRB5_CC_COLLECTION
/* krb5 profile functions */
#include <profile.h>
#endif
const int opt_id, char **lifetime_str)
{
int ret;
*lifetime_str = NULL;
return EOK;
}
goto done;
}
goto done;
}
} else {
goto done;
}
}
if (ret != 0) {
goto done;
}
*lifetime_str = str;
done:
}
return ret;
}
#ifdef HAVE_KRB5_CC_COLLECTION
/* source default_ccache_name from krb5.conf */
char **ccname)
{
profile_t p;
long ret;
profile_release(p);
if (!value) {
ret = ERR_NOT_FOUND;
goto done;
}
goto done;
}
done:
return ret;
}
#else
char **ccname)
{
"Your kerberos library does not support the default_ccache_name "
"option or the profile library. Please use krb5_ccname_template "
"in sssd.conf if you want to change the default\n");
return ERR_NOT_FOUND;
}
#endif
{
if (template_len >= 6 &&
"contain randomizing characters (XXXXXX), file might not "
"be rewritable\n", cc_template);
}
}
struct sss_domain_info *dom,
{
int ret;
const char *realm;
const char *dummy;
char *ccname;
return EINVAL;
}
if (!tmp_ctx) {
goto done;
}
goto done;
}
}
"Failed to set realm, krb5_child might not work as expected.\n");
}
"Failed to check value of krb5_renewable_lifetime. [%d][%s]\n",
goto done;
}
&krb5_ctx->lifetime_str);
"Failed to check value of krb5_lifetime. [%d][%s]\n",
goto done;
}
goto done;
}
}
}
/* In contrast to MIT KDCs AD does not automatically canonicalize the
* enterprise principal in an AS request but requires the canonicalize
* flags to be set. To be on the safe side we always enable
* canonicalization if enterprise principals are used. */
krb5_ctx->canonicalize = false;
krb5_ctx->canonicalize = true;
}
}
"using the KDC or defaults.\n");
}
"The credential ccache name template has been explicitly set "
"in sssd.conf, it is recommended to set default_ccache_name "
"in krb5.conf instead so that a system default is used\n");
if (!ccname) {
goto done;
}
} else {
goto done;
}
if (ret == ERR_NOT_FOUND) {
/* Use fallback default */
if (!ccname) {
goto done;
}
}
/* set back in opts */
goto done;
}
}
/* warn if the file type (which is usally created in a sticky bit
* laden directory) does not have randomizing chracters */
if (ccname[0] == '/') {
"missing an explicit type, but is an absolute "
"path specifier. Assuming FILE:\n");
if (!ccname) {
goto done;
}
goto done;
}
}
}
done:
return ret;
}
{
if (krb5_servers == NULL) {
"No KDC found in configuration, trying legacy option\n");
return ret;
}
if (krb5_servers != NULL)
{
return ret;
}
"Set krb5 server [%s] based on legacy krb5_kdcip option\n",
"Your configuration uses the deprecated option "
"'krb5_kdcip' to specify the KDC. Please change the "
"configuration to use the 'krb5_server' option "
"instead.\n");
}
}
return EOK;
}
{
int ret;
goto done;
}
/* If there is no KDC, try the deprecated krb5_kdcip option, too */
/* FIXME - this can be removed in a future version */
goto done;
}
done:
}
return ret;
}
const char *service)
{
int ret;
"Missing or empty realm, server or service.\n");
return EINVAL;
}
if (sss_krb5_realm_has_proxy(realm)) {
"KDC Proxy available for realm [%s], no kdcinfo file created.\n",
realm);
return EOK;
}
} else {
return EINVAL;
}
return ENOMEM;
}
goto done;
}
if (krb5info_name == NULL) {
goto done;
}
if (fd == -1) {
goto done;
}
errno = 0;
if (written == -1) {
goto done;
}
if (written != server_len) {
"Write error, wrote [%zd] bytes, expected [%zu]\n",
goto done;
}
if (ret == -1) {
goto done;
}
fd = -1;
if (ret == -1) {
goto done;
}
if (ret == -1) {
goto done;
}
done:
if (fd != -1) {
}
return ret;
}
{
char *address;
char *safe_address;
int ret;
return;
}
if (!krb5_service) {
return;
}
if (!srvaddr) {
"FATAL: No hostent available for server (%s)\n",
return;
}
return;
}
address);
if (safe_address == NULL) {
return;
}
if (krb5_service->write_kdcinfo) {
if (safe_address == NULL) {
return;
}
krb5_service->name);
"write_krb5info_file failed, authentication might fail.\n");
}
}
return;
}
struct krb5_service *service,
const char *service_name,
const char *servers,
bool primary)
{
int i;
char *port_str;
long port;
char *server_spec;
char *endptr;
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
for (i = 0; list[i]; i++) {
if (!server_spec) {
goto done;
}
if (be_fo_is_srv_identifier(server_spec)) {
if (!primary) {
"Failed to add server [%s] to failover service: "
"SRV resolution only allowed for primary servers!\n",
list[i]);
continue;
}
BE_FO_PROTO_UDP, true, NULL);
if (ret) {
goto done;
}
continue;
}
/* Do not try to get port number if last character is ']' */
} else {
}
port = 0;
} else {
*port_str = '\0';
++port_str;
errno = 0;
if (errno != 0) {
goto done;
}
if (*endptr != '\0') {
goto done;
}
goto done;
}
port_str);
goto done;
}
} else {
goto done;
}
}
/* It could be ipv6 address in square brackets. Remove
* the brackets if needed. */
goto done;
}
goto done;
}
}
done:
return ret;
}
static inline errno_t
const char *service_name, const char *servers)
{
}
static inline errno_t
const char *service_name, const char *servers)
{
}
{
}
const char *service_name,
const char *primary_servers,
const char *backup_servers,
const char *realm,
bool use_kdcinfo,
struct krb5_service **_service)
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!service) {
goto done;
}
goto done;
}
goto done;
}
goto done;
}
if (!primary_servers) {
"No primary servers defined, using service discovery\n");
}
goto done;
}
if (backup_servers) {
goto done;
}
}
goto done;
}
done:
}
return ret;
}
{
int ret;
char *file;
return ENOMEM;
}
errno = 0;
if (ret == -1) {
}
return ENOMEM;
}
errno = 0;
if (ret == -1) {
}
return EOK;
}
{
int ret;
struct remove_info_files_ctx);
"be_fo_run_callbacks_at_next_request failed, "
"krb5 info files will not be removed, because "
"it is unclear if they will be recreated properly.\n");
return;
}
"be_fo_run_callbacks_at_next_request failed, "
"krb5 info files will not be removed, because "
"it is unclear if they will be recreated properly.\n");
return;
}
}
"talloc_new failed, cannot remove krb5 info files.\n");
return;
}
}
}
struct tevent_signal *se,
int signum,
int count,
void *siginfo,
void *private_data)
{
int ret;
}
orderly_shutdown(0);
}
{
int ret;
const char *krb5_realm;
return EINVAL;
}
return ENOMEM;
}
if (krb5_realm == NULL) {
goto done;
}
goto done;
}
} else {
}
NULL);
goto done;
}
done:
}
return ret;
}
{
const char *krb5_realm;
char *sig_realm;
BlockSignals(false, SIGTERM);
if (krb5_realm == NULL) {
return EINVAL;
}
return ENOMEM;
}
return ENOMEM;
}
return EOK;
}
{
char *upn;
char *name;
return ENOMEM;
}
goto done;
}
} else {
goto done;
}
}
/* The internal username is qualified, but we are only interested in
* the name part
*/
"Could not parse [%s] into name and "
"domain components, login might fail\n", username);
} else {
/* NOTE: this is a hack, works only in some environments */
}
goto done;
}
done:
return ret;
}
bool *different_realm)
{
char *at_sign;
return EINVAL;
}
return EINVAL;
}
*different_realm = false;
} else {
*different_realm = true;
}
return EOK;
}