summaryrefslogtreecommitdiffstats
path: root/server/krb5_plugin/sssd_krb5_locator_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/krb5_plugin/sssd_krb5_locator_plugin.c')
-rw-r--r--server/krb5_plugin/sssd_krb5_locator_plugin.c122
1 files changed, 93 insertions, 29 deletions
diff --git a/server/krb5_plugin/sssd_krb5_locator_plugin.c b/server/krb5_plugin/sssd_krb5_locator_plugin.c
index a30586c92..5e7973338 100644
--- a/server/krb5_plugin/sssd_krb5_locator_plugin.c
+++ b/server/krb5_plugin/sssd_krb5_locator_plugin.c
@@ -27,12 +27,14 @@
#include <errno.h>
#include <sys/types.h>
#include <netdb.h>
-
+#include <sys/stat.h>
+#include <fcntl.h>
#include <krb5/locate_plugin.h>
#include "providers/krb5/krb5_common.h"
+#define BUFSIZE 512
#define SSSD_KRB5_LOCATOR_DEBUG "SSSD_KRB5_LOCATOR_DEBUG"
#define DEBUG_KEY "[sssd_krb5_locator] "
#define PLUGIN_DEBUG(body) do { \
@@ -67,33 +69,60 @@ void debug_fn(const char *format, ...)
free(s);
}
-krb5_error_code sssd_krb5_locator_init(krb5_context context,
- void **private_data)
+static int get_kdcinfo(const char *realm, struct sssd_ctx *ctx)
{
- struct sssd_ctx *ctx;
- const char *dummy;
int ret;
+ char *kdcinfo_name = NULL;
+ size_t len;
+ uint8_t buf[BUFSIZE + 1];
+ uint8_t *p;
+ int fd = -1;
+
+ len = strlen(realm) + strlen(KDCINFO_TMPL);
+
+ kdcinfo_name = calloc(1, len + 1);
+ if (kdcinfo_name == NULL) {
+ PLUGIN_DEBUG(("malloc failed.\n"));
+ return ENOMEM;
+ }
- ctx = calloc(1,sizeof(struct sssd_ctx));
- if (ctx == NULL) return ENOMEM;
+ ret = snprintf(kdcinfo_name, len, KDCINFO_TMPL, realm);
+ if (ret < 0) {
+ PLUGIN_DEBUG(("snprintf failed"));
+ ret = EINVAL;
+ }
+ kdcinfo_name[len] = '\0';
- dummy = getenv(SSSD_KRB5_LOCATOR_DEBUG);
- if (dummy == NULL) {
- ctx->debug = false;
- } else {
- ctx->debug = true;
- PLUGIN_DEBUG(("sssd_krb5_locator_init called\n"));
+ fd = open(kdcinfo_name, O_RDONLY);
+ if (fd == -1) {
+ PLUGIN_DEBUG(("open failed [%d][%s].\n", errno, strerror(errno)));
+ ret = errno;
+ goto done;
}
- dummy = getenv(SSSD_KRB5_REALM);
- if (dummy == NULL) goto failed;
- ctx->sssd_realm = strdup(dummy);
- if (ctx->sssd_realm == NULL) goto failed;
+ len = BUFSIZE;
+ p = buf;
+ memset(buf, 0, BUFSIZE+1);
+ while (len != 0 && (ret = read(fd, p, len)) != 0) {
+ if (ret == -1) {
+ if (errno == EINTR) continue;
+ PLUGIN_DEBUG(("read failed [%d][%s].\n", errno, strerror(errno)));
+ close(fd);
+ goto done;
+ }
- dummy = getenv(SSSD_KRB5_KDC);
- if (dummy == NULL) goto failed;
+ len -= ret;
+ p += ret;
+ }
+ close(fd);
- ret = getaddrinfo(dummy, "kerberos", NULL, &ctx->sssd_kdc_addrinfo);
+ if (len == 0) {
+ PLUGIN_DEBUG(("Content of kdcinfo file [%s] is [%d] or larger.\n",
+ kdcinfo_name, BUFSIZE));
+ }
+ PLUGIN_DEBUG(("Found kdcinfo [%s].\n", buf));
+
+ ret = getaddrinfo((char *) buf, "kerberos", NULL, &ctx->sssd_kdc_addrinfo);
if (ret != 0) {
PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", ret,
gai_strerror(ret)));
@@ -101,20 +130,43 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", errno,
strerror(errno)));
}
- goto failed;
+ goto done;
}
- *private_data = ctx;
+ ctx->sssd_realm = strdup(realm);
+ if (ctx->sssd_realm == NULL) {
+ PLUGIN_DEBUG(("strdup failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
- return 0;
-failed:
- freeaddrinfo(ctx->sssd_kdc_addrinfo);
- free(ctx->sssd_realm);
- free(ctx);
- private_data = NULL;
- return EINVAL;
+done:
+ free(kdcinfo_name);
+ return ret;
+}
+
+krb5_error_code sssd_krb5_locator_init(krb5_context context,
+ void **private_data)
+{
+ struct sssd_ctx *ctx;
+ const char *dummy;
+
+ ctx = calloc(1,sizeof(struct sssd_ctx));
+ if (ctx == NULL) return ENOMEM;
+
+ dummy = getenv(SSSD_KRB5_LOCATOR_DEBUG);
+ if (dummy == NULL) {
+ ctx->debug = false;
+ } else {
+ ctx->debug = true;
+ PLUGIN_DEBUG(("sssd_krb5_locator_init called\n"));
+ }
+
+ *private_data = ctx;
+
+ return 0;
}
void sssd_krb5_locator_close(void *private_data)
@@ -150,6 +202,18 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE;
ctx = (struct sssd_ctx *) private_data;
+ if (ctx->sssd_realm == NULL || strcmp(ctx->sssd_realm, realm) != 0) {
+ freeaddrinfo(ctx->sssd_kdc_addrinfo);
+ ctx->sssd_kdc_addrinfo = NULL;
+ free(ctx->sssd_realm);
+ ctx->sssd_realm = NULL;
+ ret = get_kdcinfo(realm, ctx);
+ if (ret != EOK) {
+ PLUGIN_DEBUG(("get_kdcinfo failed.\n"));
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+ }
+
PLUGIN_DEBUG(("sssd_realm[%s] requested realm[%s] family[%d] socktype[%d] "
"locate_service[%d]\n", ctx->sssd_realm, realm, family,
socktype, svc));