summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2011-12-02 11:59:20 -0500
committerStephen Gallagher <sgallagh@redhat.com>2011-12-05 13:49:58 -0500
commitd488258da8c9d419af6d8ac4f88732b6494455c4 (patch)
treea3000643d499856820d0e5fd198d0a98fb817e7a
parent46dfa69060f22a443d4ad9d2bf34441ff1adf2d3 (diff)
downloadsssd-d488258da8c9d419af6d8ac4f88732b6494455c4.tar.gz
sssd-d488258da8c9d419af6d8ac4f88732b6494455c4.tar.xz
sssd-d488258da8c9d419af6d8ac4f88732b6494455c4.zip
Allow using Glib for UTF8 support
-rw-r--r--Makefile.am29
-rw-r--r--configure.ac14
-rw-r--r--src/conf_macros.m420
-rw-r--r--src/external/glib.m411
-rw-r--r--src/providers/ipa/hbac_evaluator.c44
-rw-r--r--src/responder/common/responder_common.c10
-rw-r--r--src/util/sss_utf8.c119
-rw-r--r--src/util/sss_utf8.h43
8 files changed, 236 insertions, 54 deletions
diff --git a/Makefile.am b/Makefile.am
index 87def30b2..17d3dd6af 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,8 @@ pubconfpath = @pubconfpath@
pkgconfigdir = $(libdir)/pkgconfig
krb5rcachedir = @krb5rcachedir@
+UNICODE_LIBS=@UNICODE_LIBS@
+
AM_CFLAGS =
if WANT_AUX_INFO
AM_CFLAGS += -aux-info $@.X
@@ -118,7 +120,8 @@ krb5plugin_LTLIBRARIES = \
endif
noinst_LTLIBRARIES = \
- libsss_crypt.la
+ libsss_crypt.la \
+ libsss_utf8.la
if HAVE_NSS
SSS_CRYPT_SOURCES = src/util/crypto/nss/nss_sha512crypt.c \
@@ -141,6 +144,9 @@ libsss_crypt_la_CFLAGS = \
libsss_crypt_la_LIBADD = \
$(SSS_CRYPT_LIBS)
+libsss_utf8_la_SOURCES = src/util/sss_utf8.c
+libsss_utf8_la_LIBADD = $(UNICODE_LIBS)
+
if BUILD_PYTHON_BINDINGS
pyexec_LTLIBRARIES = \
pysss.la \
@@ -188,6 +194,7 @@ AM_CPPFLAGS = \
$(INI_CONFIG_CFLAGS) \
$(DHASH_CFLAGS) \
$(LIBNL_CFLAGS) \
+ $(GLIB2_CFLAGS) \
-DLIBDIR=\"$(libdir)\" \
-DVARDIR=\"$(localstatedir)\" \
-DSHLIBEXT=\"$(SHLIBEXT)\" \
@@ -268,7 +275,8 @@ SSSD_LIBS = \
$(SSS_CRYPT_LIBS) \
$(OPENLDAP_LIBS) \
$(TDB_LIBS) \
- libsss_crypt.la
+ libsss_crypt.la \
+ libsss_utf8.la
PYTHON_BINDINGS_LIBS = \
$(TALLOC_LIBS) \
@@ -293,8 +301,9 @@ TOOLS_LIBS = \
$(INI_CONFIG_LIBS) \
$(COLLECTION_LIBS) \
$(DHASH_LIBS) \
- $(OPENLDAP_LIBS) \
- $(TDB_LIBS) \
+ $(OPENLDAP_LIBS) \
+ $(TDB_LIBS) \
+ $(UNICODE_LIBS) \
libsss_crypt.la
if BUILD_SELINUX
@@ -315,6 +324,7 @@ dist_noinst_HEADERS = \
src/util/sss_ldap.h \
src/util/sss_python.h \
src/util/sss_krb5.h \
+ src/util/sss_utf8.h \
src/util/refcount.h \
src/util/find_uid.h \
src/util/user_info_msg.h \
@@ -367,14 +377,13 @@ if HAVE_NSS
dist_noinst_HEADERS += src/util/crypto/nss/nss_util.h
endif
-
lib_LTLIBRARIES = libipa_hbac.la
dist_pkgconfig_DATA += src/providers/ipa/ipa_hbac.pc
libipa_hbac_la_SOURCES = \
src/providers/ipa/hbac_evaluator.c
libipa_hbac_la_LDFLAGS = \
- -version 1:0:1 \
- -lunistring
+ -version 1:0:1
+libipa_hbac_la_LIBADD = libsss_utf8.la
include_HEADERS = \
src/providers/ipa/ipa_hbac.h
@@ -399,8 +408,7 @@ sssd_nss_SOURCES = \
$(SSSD_RESPONDER_OBJ)
sssd_nss_LDADD = \
$(TDB_LIBS) \
- $(SSSD_LIBS) \
- -lunistring
+ $(SSSD_LIBS)
sssd_pam_SOURCES = \
src/responder/pam/pam_LOCAL_domain.c \
@@ -411,8 +419,7 @@ sssd_pam_SOURCES = \
$(SSSD_RESPONDER_OBJ)
sssd_pam_LDADD = \
$(TDB_LIBS) \
- $(SSSD_LIBS) \
- -lunistring
+ $(SSSD_LIBS)
sssd_be_SOURCES = \
src/providers/data_provider_be.c \
diff --git a/configure.ac b/configure.ac
index 5e0878bca..5417d53a0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,7 +123,19 @@ m4_include([src/external/nsupdate.m4])
m4_include([src/external/libkeyutils.m4])
m4_include([src/external/libnl.m4])
m4_include([src/util/signal.m4])
-m4_include([src/external/libunistring.m4])
+
+WITH_UNICODE_LIB
+if test x$unicode_lib = xlibunistring; then
+ m4_include([src/external/libunistring.m4])
+ AC_DEFINE_UNQUOTED(HAVE_LIBUNISTRING, 1, [Using libunistring for unicode])
+ UNICODE_LIBS=-lunistring
+ AC_SUBST(UNICODE_LIBS)
+else
+ m4_include([src/external/glib.m4])
+ AC_DEFINE_UNQUOTED(HAVE_GLIB2, 1, [Using libunistring for unicode])
+ UNICODE_LIBS=$GLIB2_LIBS
+ AC_SUBST(UNICODE_LIBS)
+fi
PKG_CHECK_MODULES([DBUS],[dbus-1])
dnl if test -n "`$PKG_CONFIG --modversion dbus-1 | grep '^0\.'`" ; then
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
index 2a109b5f8..81d945eda 100644
--- a/src/conf_macros.m4
+++ b/src/conf_macros.m4
@@ -280,3 +280,23 @@ AC_DEFUN([WITH_NOLOGIN_SHELL],
fi
AC_DEFINE_UNQUOTED(NOLOGIN_SHELL, "$nologin_shell", [The shell used to deny access to users])
])
+
+AC_DEFUN([WITH_UNICODE_LIB],
+ [ AC_ARG_WITH([unicode-lib],
+ [AC_HELP_STRING([--with-unicode-lib=<library>],
+ [Which library to use for unicode processing (libunistring, glib2) [libunistring]]
+ )
+ ]
+ )
+ unicode_lib="libunistring"
+ if test x"$with_unicode_lib" != x; then
+ unicode_lib=$with_unicode_lib
+ fi
+
+ if test x"$unicode_lib" != x"libunistring" -a x"$unicode_lib" != x"glib2"; then
+ AC_MSG_ERROR([Unsupported unicode library])
+ fi
+
+ AM_CONDITIONAL([WITH_LIBUNISTRING], test x"$unicode_lib" = x"libunistring")
+ AM_CONDITIONAL([WITH_GLIB], test x"$unicode_lib" = x"glib2")
+ ])
diff --git a/src/external/glib.m4 b/src/external/glib.m4
new file mode 100644
index 000000000..fe9a8272e
--- /dev/null
+++ b/src/external/glib.m4
@@ -0,0 +1,11 @@
+PKG_CHECK_MODULES([GLIB2],[glib-2.0])
+
+if test x$has_glib2 != xno; then
+ SAFE_LIBS="$LIBS"
+ LIBS="$GLIB2_LIBS"
+
+ AC_CHECK_FUNC([g_utf8_validate],
+ AC_DEFINE([HAVE_G_UTF8_VALIDATE], [1],
+ [Define if g_utf8_validate exists]))
+ LIBS="$SAFE_LIBS"
+fi \ No newline at end of file
diff --git a/src/providers/ipa/hbac_evaluator.c b/src/providers/ipa/hbac_evaluator.c
index 476ad6482..a41aa5bb6 100644
--- a/src/providers/ipa/hbac_evaluator.c
+++ b/src/providers/ipa/hbac_evaluator.c
@@ -25,10 +25,9 @@
#include <stdlib.h>
#include <string.h>
-#include <unistr.h>
-#include <unicase.h>
#include <errno.h>
#include "providers/ipa/ipa_hbac.h"
+#include "util/sss_utf8.h"
#ifndef HAVE_ERRNO_T
#define HAVE_ERRNO_T
@@ -240,7 +239,6 @@ static errno_t hbac_evaluate_element(struct hbac_rule_element *rule_el,
size_t i, j;
const uint8_t *rule_name;
const uint8_t *req_name;
- int result;
int ret;
if (rule_el->category & HBAC_CATEGORY_ALL) {
@@ -255,21 +253,11 @@ static errno_t hbac_evaluate_element(struct hbac_rule_element *rule_el,
rule_name = (const uint8_t *) rule_el->names[i];
req_name = (const uint8_t *) req_el->name;
- /* Do a case-insensitive comparison.
- * The input must be encoded in UTF8.
- * We have no way of knowing the language,
- * so we'll pass NULL for the language and
- * hope for the best.
- */
- errno = 0;
- ret = u8_casecmp(rule_name, u8_strlen(rule_name),
- req_name, u8_strlen(req_name),
- NULL, NULL, &result);
- if (ret < 0) {
- return errno;
- }
-
- if (result == 0) {
+ /* Do a case-insensitive comparison. */
+ ret = sss_utf8_case_eq(rule_name, req_name);
+ if (ret != EOK && ret != ENOMATCH) {
+ return ret;
+ } else if (ret == EOK) {
*matched = true;
return EOK;
}
@@ -287,21 +275,11 @@ static errno_t hbac_evaluate_element(struct hbac_rule_element *rule_el,
for (j = 0; req_el->groups[j]; j++) {
req_name = (const uint8_t *) req_el->groups[j];
- /* Do a case-insensitive comparison.
- * The input must be encoded in UTF8.
- * We have no way of knowing the language,
- * so we'll pass NULL for the language and
- * hope for the best.
- */
- errno = 0;
- ret = u8_casecmp(rule_name, u8_strlen(rule_name),
- req_name, u8_strlen(req_name),
- NULL, NULL, &result);
- if (ret < 0) {
- return errno;
- }
-
- if (result == 0) {
+ /* Do a case-insensitive comparison. */
+ ret = sss_utf8_case_eq(rule_name, req_name);
+ if (ret != EOK && ret != ENOMATCH) {
+ return ret;
+ } else if (ret == EOK) {
*matched = true;
return EOK;
}
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 5389031bc..af7a99efd 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -33,9 +33,9 @@
#include <sys/time.h>
#include <errno.h>
#include <popt.h>
-#include <unistr.h>
#include "config.h"
#include "util/util.h"
+#include "util/sss_utf8.h"
#include "db/sysdb.h"
#include "confdb/confdb.h"
#include "dbus/dbus.h"
@@ -683,11 +683,3 @@ int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
return EOK;
}
-
-bool sss_utf8_check(const uint8_t *s, size_t n)
-{
- if (u8_check(s, n) == NULL) {
- return true;
- }
- return false;
-}
diff --git a/src/util/sss_utf8.c b/src/util/sss_utf8.c
new file mode 100644
index 000000000..4a98233bb
--- /dev/null
+++ b/src/util/sss_utf8.c
@@ -0,0 +1,119 @@
+/*
+ SSSD
+
+ Authors:
+ Stephen Gallagher <sgallagh@redhat.com>
+
+ Copyright (C) 2011 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ 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 "util/util.h"
+#include "sss_utf8.h"
+
+#ifdef HAVE_LIBUNISTRING
+bool sss_utf8_check(const uint8_t *s, size_t n)
+{
+ if (u8_check(s, n) == NULL) {
+ return true;
+ }
+ return false;
+}
+
+#elif HAVE_GLIB2
+bool sss_utf8_check(const uint8_t *s, size_t n)
+{
+ return g_utf8_validate((const gchar *)s, n, NULL);
+}
+
+#else
+#error No unicode library
+#endif
+
+/* Returns EOK on match, ENOTUNIQ if comparison succeeds but
+ * does not match.
+ * May return other errno error codes on failure
+ */
+#ifdef HAVE_LIBUNISTRING
+errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2)
+{
+
+ /* Do a case-insensitive comparison.
+ * The input must be encoded in UTF8.
+ * We have no way of knowing the language,
+ * so we'll pass NULL for the language and
+ * hope for the best.
+ */
+ int ret;
+ int resultp;
+ size_t n1, n2;
+ errno = 0;
+
+ n1 = u8_strlen(s1);
+ n2 = u8_strlen(s2);
+
+ ret = u8_casecmp(s1, n1,
+ s2, n2,
+ NULL, NULL,
+ &resultp);
+ if (ret < 0) {
+ /* An error occurred */
+ return errno;
+ }
+
+ if (resultp == 0) {
+ return EOK;
+ }
+ return ENOMATCH;
+}
+
+#elif HAVE_GLIB2
+errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2)
+{
+ gchar *gs1;
+ gchar *gs2;
+ gssize n1, n2;
+ gint gret;
+ errno_t ret;
+
+ n1 = g_utf8_strlen((const gchar *)s1, -1);
+ n2 = g_utf8_strlen((const gchar *)s2, -1);
+
+ gs1 = g_utf8_casefold((const gchar *)s1, n1);
+ if (gs1 == NULL) {
+ return ENOMEM;
+ }
+
+ gs2 = g_utf8_casefold((const gchar *)s2, n2);
+ if (gs2 == NULL) {
+ return ENOMEM;
+ }
+
+ gret = g_utf8_collate(gs1, gs2);
+ if (gret == 0) {
+ ret = EOK;
+ } else {
+ ret = ENOMATCH;
+ }
+
+ g_free(gs1);
+ g_free(gs2);
+
+ return ret;
+}
+
+#else
+#error No unicode library
+#endif
diff --git a/src/util/sss_utf8.h b/src/util/sss_utf8.h
new file mode 100644
index 000000000..37dcff959
--- /dev/null
+++ b/src/util/sss_utf8.h
@@ -0,0 +1,43 @@
+/*
+ SSSD
+
+ Authors:
+ Stephen Gallagher <sgallagh@redhat.com>
+
+ Copyright (C) 2011 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ 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/>.
+*/
+
+#ifndef SSS_UTF8_H_
+#define SSS_UTF8_H_
+
+#ifdef HAVE_LIBUNISTRING
+#include <unistr.h>
+#include <unicase.h>
+#elif HAVE_GLIB2
+#include <glib.h>
+#endif
+#include "util/util.h"
+
+#ifndef ENOMATCH
+#define ENOMATCH -1
+#endif
+
+bool sss_utf8_check(const uint8_t *s, size_t n);
+
+errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2);
+
+
+#endif /* SSS_UTF8_H_ */