diff options
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | src/krb5_plugin/sssd_krb5_localauth_plugin.c | 159 |
2 files changed, 167 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 64c017ea0..1b183d023 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2485,10 +2485,18 @@ endif if BUILD_KRB5_LOCALAUTH_PLUGIN sssd_krb5_localauth_plugin_la_SOURCES = \ - src/krb5_plugin/sssd_krb5_localauth_plugin.c + src/krb5_plugin/sssd_krb5_localauth_plugin.c \ + src/util/murmurhash3.c \ + src/util/io.c \ + src/sss_client/common.c \ + src/sss_client/nss_mc_common.c \ + src/sss_client/nss_mc_passwd.c \ + src/sss_client/nss_passwd.c sssd_krb5_localauth_plugin_la_CFLAGS = \ $(AM_CFLAGS) \ $(KRB5_CFLAGS) +sssd_krb5_localauth_plugin_la_LIBADD = \ + $(KRB5_LIBS) sssd_krb5_localauth_plugin_la_LDFLAGS = \ -avoid-version \ -module diff --git a/src/krb5_plugin/sssd_krb5_localauth_plugin.c b/src/krb5_plugin/sssd_krb5_localauth_plugin.c index 93fbbc295..83a286689 100644 --- a/src/krb5_plugin/sssd_krb5_localauth_plugin.c +++ b/src/krb5_plugin/sssd_krb5_localauth_plugin.c @@ -18,11 +18,168 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <nss.h> +#include <sys/types.h> +#include <pwd.h> +#include <string.h> +#include <strings.h> +#include <errno.h> + #include <krb5/localauth_plugin.h> +enum nss_status _nss_sss_getpwnam_r(const char *name, struct passwd *result, + char *buffer, size_t buflen, int *errnop); + +#define DEFAULT_BUFSIZE 4096 + +static krb5_error_code sss_userok(krb5_context context, + krb5_localauth_moddata data, + krb5_const_principal aname, + const char *lname) +{ + krb5_error_code kerr; + char *princ_str; + struct passwd pwd = { 0 }; + char *buffer = NULL; + size_t buflen; + enum nss_status nss_status; + int nss_errno; + uid_t princ_uid; + int ret; + + kerr = krb5_unparse_name(context, aname, &princ_str); + if (kerr != 0) { + return kerr; + } + + if (strcasecmp(princ_str, lname) == 0) { + ret = 0; + goto done; + } + + buflen = DEFAULT_BUFSIZE; + buffer = malloc(buflen); + if (buffer == NULL) { + ret = ENOMEM; + goto done; + } + + nss_status = _nss_sss_getpwnam_r(princ_str, &pwd, buffer, buflen, + &nss_errno); + if (nss_status != NSS_STATUS_SUCCESS) { + if (nss_status == NSS_STATUS_NOTFOUND) { + ret = KRB5_PLUGIN_NO_HANDLE; + } else { + ret = EIO; + } + goto done; + } + + princ_uid = pwd.pw_uid; + + nss_status = _nss_sss_getpwnam_r(lname, &pwd, buffer, buflen, &nss_errno); + if (nss_status != NSS_STATUS_SUCCESS) { + if (nss_status == NSS_STATUS_NOTFOUND) { + ret = KRB5_PLUGIN_NO_HANDLE; + } else { + ret = EIO; + } + goto done; + } + + if (princ_uid != pwd.pw_uid) { + ret = EPERM; + goto done; + } + + ret = 0; + +done: + krb5_free_unparsed_name(context, princ_str); + free(buffer); + + return ret; +} + +static krb5_error_code sss_an2ln(krb5_context context, + krb5_localauth_moddata data, + const char *type, const char *residual, + krb5_const_principal aname, char **lname_out) +{ + krb5_error_code kerr; + char *princ_str; + struct passwd pwd = { 0 }; + char *buffer = NULL; + size_t buflen; + enum nss_status nss_status; + int nss_errno; + int ret; + char *str; + + kerr = krb5_unparse_name(context, aname, &princ_str); + if (kerr != 0) { + return kerr; + } + + buflen = DEFAULT_BUFSIZE; + buffer = malloc(buflen); + if (buffer == NULL) { + ret = ENOMEM; + goto done; + } + + nss_status = _nss_sss_getpwnam_r(princ_str, &pwd, buffer, buflen, + &nss_errno); + if (nss_status != NSS_STATUS_SUCCESS) { + if (nss_status == NSS_STATUS_NOTFOUND) { + ret = KRB5_PLUGIN_NO_HANDLE; + } else { + ret = EIO; + } + goto done; + } + + str = strdup(pwd.pw_name); + if (str == NULL) { + ret = ENOMEM; + goto done; + } + + *lname_out = str; + + ret = 0; + +done: + krb5_free_unparsed_name(context, princ_str); + free(buffer); + + return ret; +} + +static void sss_freestr(krb5_context context, + krb5_localauth_moddata data, char *str) +{ + free(str); +} + krb5_error_code localauth_sssd_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { - return KRB5_PLUGIN_VER_NOTSUPP; + + if (maj_ver != 1 || min_ver != 1) { + return KRB5_PLUGIN_VER_NOTSUPP; + } + + krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable; + + vt->init = NULL; + vt->fini = NULL; + vt->name = "sssd"; + vt->an2ln = sss_an2ln; + vt->userok = sss_userok; + vt->free_string = sss_freestr; + + return 0; } + |