summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-07-17 21:08:20 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-09-02 10:39:42 +0200
commit6b5044001e4b0a0caf971a2cf5f27674e0d270f4 (patch)
tree19adf0edd19e578245245767ee51d162d30e3555
parent8a5e793a0576250da80371e53aa3e7eba15cdb63 (diff)
downloadsssd-6b5044001e4b0a0caf971a2cf5f27674e0d270f4.tar.gz
sssd-6b5044001e4b0a0caf971a2cf5f27674e0d270f4.tar.xz
sssd-6b5044001e4b0a0caf971a2cf5f27674e0d270f4.zip
Implement MIT Kerberos localauth plugin
The MIT Kerberos localauth pluing interface defines two different calls. The first checks if a given Kerberos principal relates to a given name of a local user (userok). The implementation lets SSSD resolve the principal and the user name and if the returned user entries both have the same UID success is returned. The second translates a given Kerberos principal to a local user name (a2l). Here SSSD is only called once to resolve the principal and the user name is returned. Resolves https://fedorahosted.org/sssd/ticket/1835 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--Makefile.am10
-rw-r--r--src/krb5_plugin/sssd_krb5_localauth_plugin.c159
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;
}
+