From b4b8297678f13581932838509700b311daef0c07 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sat, 30 Oct 2010 12:16:13 +0200 Subject: [PATCH] Support for local UUIDs --- bin/misc/uuidtest.c | 6 +-- configure.in | 40 ++++++++++++++---- etc/afpd/afp_config.c | 8 ---- etc/afpd/auth.c | 9 ++-- include/atalk/uuid.h | 6 +-- libatalk/Makefile.am | 10 ++--- libatalk/acl/Makefile.am | 13 +++--- libatalk/acl/cache.c | 1 - libatalk/acl/ldap.c | 9 ++++ libatalk/acl/ldap_config.c | 5 +-- libatalk/acl/uuid.c | 87 ++++++++++++++++++++++++++------------ 11 files changed, 119 insertions(+), 75 deletions(-) diff --git a/bin/misc/uuidtest.c b/bin/misc/uuidtest.c index 4385a3ee..b0e5ef9f 100644 --- a/bin/misc/uuidtest.c +++ b/bin/misc/uuidtest.c @@ -56,8 +56,7 @@ static void parse_ldapconf() exit(EXIT_FAILURE); } } else { - printf("afp_ldap.conf is not ok.\n"); - exit(EXIT_FAILURE); + printf("afp_ldap.conf is not ok, not using LDAP. Only local UUID testing available.\n"); } inited = 1; } @@ -65,12 +64,11 @@ static void parse_ldapconf() int main( int argc, char **argv) { - int ret, i, c; + int ret, c; int verbose = 0; atalk_uuid_t uuid; int logsetup = 0; uuidtype_t type; - char *uuidstring = NULL; char *name = NULL; while ((c = getopt(argc, argv, ":vu:g:i:")) != -1) { diff --git a/configure.in b/configure.in index 29a03904..47417f45 100644 --- a/configure.in +++ b/configure.in @@ -972,6 +972,37 @@ AC_ARG_ENABLE(overwrite, ) AC_MSG_RESULT([$OVERWRITE_CONFIG]) +dnl --------------------- check for LDAP support, for client-side ACL visibility +AC_MSG_CHECKING(for LDAP (necessary for client-side ACL visibility)) +AC_ARG_WITH(ldap, + [AS_HELP_STRING([--with-ldap], + [LDAP support (default=auto)])], + [ case "$withval" in + yes|no) + with_ldap="$withval" + ;; + *) + with_ldap=auto + ;; + esac ], + [with_ldap=auto]) +AC_MSG_RESULT($with_ldap) +if test x"$with_ldap" = x"no"; then + AC_MSG_RESULT(Disabling LDAP support) +else + with_ldap=yes + AC_MSG_NOTICE([Checking for LDAP header and library]) + AC_CHECK_HEADER([ldap.h],, + [AC_MSG_ERROR([LDAP client headers not found.]) + with_ldap=no]) + AC_CHECK_LIB(ldap, ldap_init,, + [AC_MSG_ERROR([LDAP client libs not found.]) + with_ldap=no]) +fi +if test x"$with_ldap" = x"yes"; then + AC_DEFINE(HAVE_LDAP,1,[Whether LDAP is available]) +fi + dnl --------------------- check for ACL support AC_MSG_CHECKING(whether to support ACLs) AC_ARG_WITH(acls, @@ -993,14 +1024,6 @@ if test x"$with_acl_support" = x"no"; then AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support should be built in]) else with_acl_support=yes - AC_MSG_NOTICE([ACL support requires LDAP support, checking whether that's available]) - AC_CHECK_HEADER([ldap.h],, - [AC_MSG_ERROR([ACL Support prerequisite LDAP client headers not found.]) - with_acl_support=no]) - - AC_CHECK_LIB(ldap, ldap_init,, - [AC_MSG_ERROR([ACL Support prerequisite LDAP client libs not found.]) - with_acl_support=no]) fi if test x"$with_acl_support" = x"yes" ; then @@ -1247,6 +1270,7 @@ AM_CONDITIONAL(COMPILE_A2BOOT, test x$compile_a2boot = xyes) AM_CONDITIONAL(HAVE_LIBGCRYPT, test x$neta_cv_have_libgcrypt = xyes) AM_CONDITIONAL(HAVE_OPENSSL, test x$neta_cv_have_openssl = xyes) AM_CONDITIONAL(HAVE_ACLS, test x"$with_acl_support" = x"yes") +AM_CONDITIONAL(HAVE_LDAP, test x"$with_ldap" = x"yes") AM_CONDITIONAL(USE_DHX, test x$neta_cv_compile_dhx = xyes) AM_CONDITIONAL(USE_DHX2, test x$neta_cv_compile_dhx2 = xyes) AM_CONDITIONAL(USE_RANDNUM, test x$neta_cv_have_openssl = xyes) diff --git a/etc/afpd/afp_config.c b/etc/afpd/afp_config.c index c737023d..198f03d8 100644 --- a/etc/afpd/afp_config.c +++ b/etc/afpd/afp_config.c @@ -585,14 +585,6 @@ AFPConfig *configinit(struct afp_options *cmdline) if (!afp_options_parseline(p, &options)) continue; -#ifdef HAVE_ACLS - /* Enable UUID support if LDAP config is complete */ - if (!ldap_config_valid) { - LOG(log_info, logtype_afpd, "Disabling UUID support"); - options.flags &= ~OPTION_UUID; - } -#endif /* HAVE_ACLS */ - /* AFPConfigInit can return two linked configs due to DSI and ASP */ if (!first) { if ((first = AFPConfigInit(&options, cmdline))) diff --git a/etc/afpd/auth.c b/etc/afpd/auth.c index 5cfa47c1..6027b851 100644 --- a/etc/afpd/auth.c +++ b/etc/afpd/auth.c @@ -26,9 +26,6 @@ #include #include #include -#include -#include -#include #ifdef TRU64 #include @@ -39,6 +36,10 @@ extern void afp_get_cmdline( int *ac, char ***av ); #endif /* TRU64 */ +#include +#include +#include + #include "globals.h" #include "auth.h" #include "uam_auth.h" @@ -1006,7 +1007,6 @@ int afp_getuserinfo(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, memcpy(bitmapp, &bitmap, sizeof(bitmap)); } else { LOG(log_debug, logtype_afpd, "afp_getuserinfo: get UUID for \'%s\'", obj->username); -#ifdef HAVE_ACLS int ret; atalk_uuid_t uuid; ret = getuuidfromname( obj->username, UUID_USER, uuid); @@ -1021,7 +1021,6 @@ int afp_getuserinfo(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, *rbuflen += UUID_BINSIZE; } } -#endif /* HAVE_ACLS */ LOG(log_debug, logtype_afpd, "END afp_getuserinfo:"); return AFP_OK; diff --git a/include/atalk/uuid.h b/include/atalk/uuid.h index 729a41fb..e3b2be11 100644 --- a/include/atalk/uuid.h +++ b/include/atalk/uuid.h @@ -18,8 +18,8 @@ #define UUID_BINSIZE 16 #define UUID_STRINGSIZE 36 -typedef char *uuidp_t; -typedef char atalk_uuid_t[UUID_BINSIZE]; +typedef unsigned char *uuidp_t; +typedef unsigned char atalk_uuid_t[UUID_BINSIZE]; typedef enum {UUID_USER = 1, UUID_GROUP, UUID_LOCAL} uuidtype_t; extern char *uuidtype[]; @@ -42,7 +42,7 @@ extern char *ldap_uid_attr; extern int getuuidfromname( const char *name, uuidtype_t type, uuidp_t uuid); extern int getnamefromuuid( const uuidp_t uuidp, char **name, uuidtype_t *type); -extern const char *uuid_bin2string( char *uuid); +extern const char *uuid_bin2string(unsigned char *uuid); extern void uuid_string2bin( const char *uuidstring, uuidp_t uuid); #endif /* AFP_UUID_H */ diff --git a/libatalk/Makefile.am b/libatalk/Makefile.am index e51940e3..4c7500d6 100644 --- a/libatalk/Makefile.am +++ b/libatalk/Makefile.am @@ -1,13 +1,14 @@ # Makefile.am for libatalk/ -SUBDIRS = adouble asp atp bstring compat cnid dsi nbp netddp tdb util unicode vfs +SUBDIRS = acl adouble asp atp bstring compat cnid dsi nbp netddp tdb util unicode vfs lib_LTLIBRARIES = libatalk.la libatalk_la_SOURCES = dummy.c libatalk_la_LIBADD = \ + acl/libacl.la \ adouble/libadouble.la \ asp/libasp.la \ atp/libatp.la \ @@ -22,6 +23,7 @@ libatalk_la_LIBADD = \ vfs/libvfs.la libatalk_la_DEPENDENCIES = \ + acl/libacl.la \ adouble/libadouble.la \ asp/libasp.la \ atp/libatp.la \ @@ -35,11 +37,5 @@ libatalk_la_DEPENDENCIES = \ unicode/libunicode.la \ vfs/libvfs.la -if HAVE_ACLS -SUBDIRS += acl -libatalk_la_DEPENDENCIES += acl/libacl.la -libatalk_la_LIBADD += acl/libacl.la -endif - libatalk_la_LDFLAGS = -static diff --git a/libatalk/acl/Makefile.am b/libatalk/acl/Makefile.am index 43db9dfc..e7f9753a 100644 --- a/libatalk/acl/Makefile.am +++ b/libatalk/acl/Makefile.am @@ -2,15 +2,12 @@ noinst_HEADERS = aclldap.h cache.h -if HAVE_ACLS noinst_LTLIBRARIES = libacl.la -libacl_la_SOURCES = \ - ldap.c \ - uuid.c \ - cache.c \ - ldap_config.c \ - unix.c +libacl_la_SOURCES = cache.c unix.c uuid.c +libacl_la_LDFLAGS = -libacl_la_LDFLAGS = -lldap +if HAVE_LDAP +libacl_la_SOURCES += ldap.c ldap_config.c +libacl_la_LDFLAGS += -lldap endif diff --git a/libatalk/acl/cache.c b/libatalk/acl/cache.c index 1d7314cc..4c640ac2 100644 --- a/libatalk/acl/cache.c +++ b/libatalk/acl/cache.c @@ -1,5 +1,4 @@ /* - $Id: cache.c,v 1.6 2010-04-23 11:37:05 franklahm Exp $ Copyright (c) 2008,2009 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/libatalk/acl/ldap.c b/libatalk/acl/ldap.c index 5fc277b8..724ac4d5 100644 --- a/libatalk/acl/ldap.c +++ b/libatalk/acl/ldap.c @@ -16,6 +16,8 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ +#ifdef HAVE_LDAP + #include #include #include @@ -265,6 +267,9 @@ int ldap_getuuidfromname( const char *name, uuidtype_t type, char **uuid_string) char *attributes[] = { ldap_uuid_attr, NULL}; char *ldap_attr; + if (!ldap_config_valid) + return -1; + /* make filter */ if (type == UUID_GROUP) ldap_attr = ldap_group_attr; @@ -303,6 +308,9 @@ int ldap_getnamefromuuid( const char *uuidstr, char **name, uuidtype_t *type) { char filter[256]; /* this should really be enough. we dont want to malloc everything! */ char *attributes[] = { NULL, NULL}; + if (!ldap_config_valid) + return -1; + /* make filter */ len = snprintf( filter, 256, "%s=%s", ldap_uuid_attr, uuidstr); if (len >= 256 || len == -1) { @@ -328,3 +336,4 @@ int ldap_getnamefromuuid( const char *uuidstr, char **name, uuidtype_t *type) { return -1; } +#endif /* HAVE_LDAP */ diff --git a/libatalk/acl/ldap_config.c b/libatalk/acl/ldap_config.c index 9bac9f3b..a2e4ec99 100644 --- a/libatalk/acl/ldap_config.c +++ b/libatalk/acl/ldap_config.c @@ -1,5 +1,4 @@ /* - $Id: ldap_config.c,v 1.4 2009-11-28 11:10:37 franklahm Exp $ Copyright (c) 2009 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -17,7 +16,7 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#ifdef HAVE_ACLS +#ifdef HAVE_LDAP #include #include @@ -146,4 +145,4 @@ int acl_ldap_readconfig(char *name) fclose(f); return 0; } -#endif /* HAVE_ACLS */ +#endif /* HAVE_LDAP */ diff --git a/libatalk/acl/uuid.c b/libatalk/acl/uuid.c index 010de4db..1ac47f8d 100644 --- a/libatalk/acl/uuid.c +++ b/libatalk/acl/uuid.c @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include #include @@ -74,24 +77,17 @@ void uuid_string2bin( const char *uuidstring, uuidp_t uuid) { * * Returns pointer to static buffer. */ -const char *uuid_bin2string(char *uuid) { +const char *uuid_bin2string(unsigned char *uuid) { static char uuidstring[UUID_STRINGSIZE + 1]; - char ascii[16] = { "0123456789ABCDEF" }; - int nibble = 1; + int i = 0; - int c; - + unsigned char c; + while (i < UUID_STRINGSIZE) { c = *uuid; - if (nibble) - c = c >> 4; - else { - c &= 0x0f; - uuid++; - } - uuidstring[i] = ascii[c]; - nibble ^= 1; - i++; + uuid++; + sprintf(uuidstring + i, "%02X", c); + i += 2; if (i==8 || i==13 || i==18 || i==23) uuidstring[i++] = '-'; } @@ -103,6 +99,14 @@ const char *uuid_bin2string(char *uuid) { * Interface ********************************************************/ +static unsigned char local_group_uuid[] = {0xab, 0xcd, 0xef, + 0xab, 0xcd, 0xef, + 0xab, 0xcd, 0xef, + 0xab, 0xcd, 0xef}; + +static unsigned char local_user_uuid[] = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd, + 0xcc, 0xcc, 0xbb, 0xbb, 0xaa, 0xaa}; + /* * name: give me his name * type: and type (UUID_USER or UUID_GROUP) @@ -111,8 +115,9 @@ const char *uuid_bin2string(char *uuid) { */ int getuuidfromname( const char *name, uuidtype_t type, uuidp_t uuid) { int ret = 0; +#ifdef HAVE_LDAP char *uuid_string = NULL; - +#endif ret = search_cachebyname( name, type, uuid); if (ret == 0) { /* found in cache */ @@ -120,29 +125,55 @@ int getuuidfromname( const char *name, uuidtype_t type, uuidp_t uuid) { name, uuidtype[type], uuid_bin2string(uuid)); } else { /* if not found in cache */ - ret = ldap_getuuidfromname( name, type, &uuid_string); - if (ret != 0) { - LOG(log_note, logtype_afpd, "getuuidfromname(\"%s\",t:%u): no result from ldap search", +#ifdef HAVE_LDAP + if ((ret = ldap_getuuidfromname( name, type, &uuid_string)) == 0) { + uuid_string2bin( uuid_string, uuid); + LOG(log_debug, logtype_afpd, "getuuidfromname{local}: name: %s, type: %s -> UUID: %s", + name, uuidtype[type], uuid_bin2string(uuid)); + } else { + LOG(log_debug, logtype_afpd, "getuuidfromname(\"%s\",t:%u): no result from ldap search", name, type); - goto cleanup; } - uuid_string2bin( uuid_string, uuid); +#endif + if (ret != 0) { + /* Build a local UUID */ + if (type == UUID_USER) { + memcpy(uuid, local_user_uuid, 12); + struct passwd *pwd; + if ((pwd = getpwnam(name)) == NULL) { + LOG(log_error, logtype_afpd, "getuuidfromname(\"%s\",t:%u): unknown user", + name, uuidtype[type]); + goto cleanup; + } + uint32_t id = pwd->pw_uid; + id = htonl(id); + memcpy(uuid + 12, &id, 4); + } else { + memcpy(uuid, &local_group_uuid, 12); + struct group *grp; + if ((grp = getgrnam(name)) == NULL) { + LOG(log_error, logtype_afpd, "getuuidfromname(\"%s\",t:%u): unknown user", + name, uuidtype[type]); + goto cleanup; + } + uint32_t id = grp->gr_gid; + id = htonl(id); + memcpy(uuid + 12, &id, 4); + } + LOG(log_debug, logtype_afpd, "getuuidfromname{local}: name: %s, type: %s -> UUID: %s", + name, uuidtype[type], uuid_bin2string(uuid)); + } + ret = 0; add_cachebyname( name, uuid, type, 0); - LOG(log_debug, logtype_afpd, "getuuidfromname{LDAP}: name: %s, type: %s -> UUID: %s",name, uuidtype[type], uuid_string); } cleanup: +#ifdef HAVE_LDAP if (uuid_string) free(uuid_string); +#endif return ret; } -static char local_group_uuid[] = {0xab, 0xcd, 0xef, - 0xab, 0xcd, 0xef, - 0xab, 0xcd, 0xef, - 0xab, 0xcd, 0xef}; - -static char local_user_uuid[] = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd, - 0xcc, 0xcc, 0xbb, 0xbb, 0xaa, 0xaa}; /* * uuidp: pointer to a uuid -- 2.39.2