diff options
Diffstat (limited to 'server/krb5_plugin')
-rw-r--r-- | server/krb5_plugin/sssd_krb5_locator_plugin.c | 131 | ||||
-rw-r--r-- | server/krb5_plugin/sssd_krb5_locator_plugin.h | 8 |
2 files changed, 139 insertions, 0 deletions
diff --git a/server/krb5_plugin/sssd_krb5_locator_plugin.c b/server/krb5_plugin/sssd_krb5_locator_plugin.c new file mode 100644 index 00000000..699cad40 --- /dev/null +++ b/server/krb5_plugin/sssd_krb5_locator_plugin.c @@ -0,0 +1,131 @@ +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> + +#include <krb5/locate_plugin.h> + +#include "krb5_plugin/sssd_krb5_locator_plugin.h" + +struct sssd_ctx { + char *sssd_realm; + char *sssd_kdc; +}; + +krb5_error_code sssd_krb5_locator_init(krb5_context context, + void **private_data) +{ + struct sssd_ctx *ctx; + char *dummy; + + ctx = calloc(1,sizeof(struct sssd_ctx)); + if (ctx == NULL) return ENOMEM; + + dummy = getenv(SSSD_REALM); + if (dummy == NULL) goto failed; + ctx->sssd_realm = strdup(dummy); + if (ctx->sssd_realm == NULL) goto failed; + + dummy = getenv(SSSD_KDC); + if (dummy == NULL) goto failed; + ctx->sssd_kdc = strdup(dummy); + if (ctx->sssd_kdc == NULL) goto failed; + + *private_data = ctx; + + return 0; +failed: + free(ctx->sssd_realm); + free(ctx->sssd_kdc); + free(ctx); + + private_data = NULL; + + return EINVAL; +} + +void sssd_krb5_locator_close(void *private_data) +{ + struct sssd_ctx *ctx; + + if (private_data == NULL) return; + + ctx = (struct sssd_ctx *) private_data; + free(ctx->sssd_realm); + free(ctx->sssd_kdc); + free(ctx); + + return; +} + +krb5_error_code sssd_krb5_locator_lookup(void *private_data, + enum locate_service_type svc, + const char *realm, + int socktype, + int family, + int (*cbfunc)(void *, int, struct sockaddr *), + void *cbdata) +{ + int ret; + struct sockaddr_in addr; + struct sssd_ctx *ctx; + + if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE; + ctx = (struct sssd_ctx *) private_data; + +#ifdef KRB5_PLUGIN_DEBUG + fprintf(stderr,"[%s][%s][%s][%d][%d][%d]\n", realm, ctx->sssd_realm, + ctx->sssd_kdc, socktype, + family, svc); +#endif + + switch (svc) { + case locate_service_kdc: + case locate_service_master_kdc: + case locate_service_kadmin: + break; + case locate_service_krb524: + case locate_service_kpasswd: + return KRB5_PLUGIN_NO_HANDLE; + default: + return EINVAL; + } + + switch (family) { + case AF_UNSPEC: + case AF_INET: + break; + default: + return KRB5_PLUGIN_NO_HANDLE; + } + + switch (socktype) { + case SOCK_STREAM: + case SOCK_DGRAM: + break; + default: + return EINVAL; + } + + if (strcmp(realm, ctx->sssd_realm) != 0) + return KRB5_PLUGIN_NO_HANDLE; + + addr.sin_family = AF_INET; + ret = inet_aton(ctx->sssd_kdc, &addr.sin_addr); + if (ret == 0) return EINVAL; + addr.sin_port = htons(88); + + ret = cbfunc(cbdata, socktype, (struct sockaddr *) &addr); + + return 0; +} + +const krb5plugin_service_locate_ftable service_locator = { + 0, /* version */ + sssd_krb5_locator_init, + sssd_krb5_locator_close, + sssd_krb5_locator_lookup, +}; diff --git a/server/krb5_plugin/sssd_krb5_locator_plugin.h b/server/krb5_plugin/sssd_krb5_locator_plugin.h new file mode 100644 index 00000000..ab41689b --- /dev/null +++ b/server/krb5_plugin/sssd_krb5_locator_plugin.h @@ -0,0 +1,8 @@ +#ifndef __SSSD_KRB5_LOCATOR_PLUGIN_H__ +#define __SSSD_KRB5_LOCATOR_PLUGIN_H__ + +#define SSSD_KDC "SSSD_KDC" +#define SSSD_REALM "SSSD_REALM" + +#endif /* __SSSD_KRB5_LOCATOR_PLUGIN_H__ */ + |