X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Facl%2Fuuid.c;h=7d6e7d620cf6ad0aaf554c814c9b0774e0ccc3d4;hb=b3c52ea7097b09cafe6002acca2c996f1f5ea2fb;hp=074d9deb8a76c1da0343292b6250d940ee09d5c2;hpb=85a8591621dc4c47417402a24df31e40bd7cae15;p=netatalk.git diff --git a/libatalk/acl/uuid.c b/libatalk/acl/uuid.c index 074d9deb..7d6e7d62 100644 --- a/libatalk/acl/uuid.c +++ b/libatalk/acl/uuid.c @@ -24,16 +24,18 @@ #include #include #include +#include #include #include #include +#include #include #include "aclldap.h" #include "cache.h" -char *uuidtype[] = {"NULL","USER", "GROUP", "LOCAL"}; +char *uuidtype[] = {"", "USER", "GROUP", "LOCAL"}; /******************************************************** * Public helper function @@ -41,7 +43,7 @@ char *uuidtype[] = {"NULL","USER", "GROUP", "LOCAL"}; static unsigned char local_group_uuid[] = {0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, - 0xab, 0xcd, 0xef, + 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef}; static unsigned char local_user_uuid[] = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd, @@ -67,16 +69,16 @@ void localuuid_from_id(unsigned char *buf, uuidtype_t type, unsigned int id) return; } -/* +/* * convert ascii string that can include dashes to binary uuid. * caller must provide a buffer. */ -void uuid_string2bin( const char *uuidstring, uuidp_t uuid) { +void uuid_string2bin( const char *uuidstring, unsigned char *uuid) { int nibble = 1; int i = 0; unsigned char c, val = 0; - - while (*uuidstring) { + + while (*uuidstring && i < UUID_BINSIZE) { c = *uuidstring; if (c == '-') { uuidstring++; @@ -100,23 +102,32 @@ void uuid_string2bin( const char *uuidstring, uuidp_t uuid) { } -/*! +/*! * Convert 16 byte binary uuid to neat ascii represantation including dashes. - * + * Use defined or default ascii mask for dash placement * Returns pointer to static buffer. */ -const char *uuid_bin2string(unsigned char *uuid) { - static char uuidstring[UUID_STRINGSIZE + 1]; - +const char *uuid_bin2string(const unsigned char *uuid) { + static char uuidstring[64]; + const char *uuidmask; int i = 0; unsigned char c; - while (i < UUID_STRINGSIZE) { +#ifdef HAVE_LDAP + if (ldap_uuid_string) + uuidmask = ldap_uuid_string; + else +#endif + uuidmask = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; + + LOG(log_debug, logtype_afpd, "uuid_bin2string{uuid}: mask: %s", uuidmask); + + while (i < strlen(uuidmask)) { c = *uuid; uuid++; sprintf(uuidstring + i, "%02X", c); i += 2; - if (i==8 || i==13 || i==18 || i==23) + if (uuidmask[i] == '-') uuidstring[i++] = '-'; } uuidstring[i] = 0; @@ -132,24 +143,34 @@ const char *uuid_bin2string(unsigned char *uuid) { * type: and type (UUID_USER or UUID_GROUP) * uuid: pointer to uuid_t storage that the caller must provide * returns 0 on success !=0 on errror - */ -int getuuidfromname( const char *name, uuidtype_t type, uuidp_t uuid) { + */ +int getuuidfromname( const char *name, uuidtype_t type, unsigned char *uuid) { int ret = 0; + uuidtype_t mytype = type; + char nulluuid[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; #ifdef HAVE_LDAP char *uuid_string = NULL; #endif - ret = search_cachebyname( name, type, uuid); + + ret = search_cachebyname(name, &mytype, uuid); + if (ret == 0) { /* found in cache */ - LOG(log_debug, logtype_afpd, "getuuidfromname{cache}: name: %s, type: %s -> UUID: %s", - name, uuidtype[type], uuid_bin2string(uuid)); + LOG(log_debug, logtype_afpd, + "getuuidfromname{cache}: name: %s, type%s: %s -> UUID: %s", + name, + (mytype & UUID_ENOENT) == UUID_ENOENT ? "[negative]" : "", + uuidtype[type & UUIDTYPESTR_MASK], + uuid_bin2string(uuid)); + if ((mytype & UUID_ENOENT) == UUID_ENOENT) + return -1; } else { /* if not found in cache */ #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)); + LOG(log_debug, logtype_afpd, "getuuidfromname{LDAP}: name: %s, type: %s -> UUID: %s", + name, uuidtype[type & UUIDTYPESTR_MASK], uuid_bin2string(uuid)); } else { LOG(log_debug, logtype_afpd, "getuuidfromname(\"%s\",t:%u): no result from ldap search", name, type); @@ -161,24 +182,31 @@ int getuuidfromname( const char *name, uuidtype_t type, uuidp_t uuid) { struct passwd *pwd; if ((pwd = getpwnam(name)) == NULL) { LOG(log_error, logtype_afpd, "getuuidfromname(\"%s\",t:%u): unknown user", - name, uuidtype[type]); - goto cleanup; + name, uuidtype[type & UUIDTYPESTR_MASK]); + mytype |= UUID_ENOENT; + memcpy(uuid, nulluuid, 16); + } else { + localuuid_from_id(uuid, UUID_USER, pwd->pw_uid); + ret = 0; + LOG(log_debug, logtype_afpd, "getuuidfromname{local}: name: %s, type: %s -> UUID: %s", + name, uuidtype[type & UUIDTYPESTR_MASK], uuid_bin2string(uuid)); } - localuuid_from_id(uuid, UUID_USER, pwd->pw_uid); } else { struct group *grp; if ((grp = getgrnam(name)) == NULL) { LOG(log_error, logtype_afpd, "getuuidfromname(\"%s\",t:%u): unknown user", - name, uuidtype[type]); - goto cleanup; + name, uuidtype[type & UUIDTYPESTR_MASK]); + mytype |= UUID_ENOENT; + memcpy(uuid, nulluuid, 16); + } else { + localuuid_from_id(uuid, UUID_GROUP, grp->gr_gid); + ret = 0; + LOG(log_debug, logtype_afpd, "getuuidfromname{local}: name: %s, type: %s -> UUID: %s", + name, uuidtype[type & UUIDTYPESTR_MASK], uuid_bin2string(uuid)); } - localuuid_from_id(uuid, UUID_GROUP, grp->gr_gid); } - 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); + add_cachebyname(name, uuid, mytype, 0); } cleanup: @@ -199,38 +227,75 @@ cleanup: */ int getnamefromuuid(const uuidp_t uuidp, char **name, uuidtype_t *type) { int ret; + uid_t uid; + gid_t gid; + struct passwd *pwd; + struct group *grp; - ret = search_cachebyuuid( uuidp, name, type); - if (ret == 0) { + if (search_cachebyuuid(uuidp, name, type) == 0) { /* found in cache */ - LOG(log_debug9, logtype_afpd, "getnamefromuuid{cache}: UUID: %s -> name: %s, type:%s", - uuid_bin2string(uuidp), *name, uuidtype[*type]); - } else { - /* not found in cache */ - - /* Check if UUID is a client local one */ - if (memcmp(uuidp, local_user_uuid, 12) == 0 - || memcmp(uuidp, local_group_uuid, 12) == 0) { - LOG(log_debug, logtype_afpd, "getnamefromuuid: local UUID: %" PRIu32 "", - ntohl(*(uint32_t *)(uuidp + 12))); - *type = UUID_LOCAL; - *name = strdup("UUID_LOCAL"); - return 0; + LOG(log_debug, logtype_afpd, + "getnamefromuuid{cache}: UUID: %s -> name: %s, type%s: %s", + uuid_bin2string(uuidp), + *name, + (*type & UUID_ENOENT) == UUID_ENOENT ? "[negative]" : "", + uuidtype[(*type) & UUIDTYPESTR_MASK]); + if ((*type & UUID_ENOENT) == UUID_ENOENT) + return -1; + return 0; + } + + /* not found in cache */ + + /* Check if UUID is a client local one */ + if (memcmp(uuidp, local_user_uuid, 12) == 0) { + *type = UUID_USER; + uid = ntohl(*(uint32_t *)(uuidp + 12)); + if ((pwd = getpwuid(uid)) == NULL) { + /* not found, add negative entry to cache */ + add_cachebyuuid(uuidp, "UUID_ENOENT", UUID_ENOENT, 0); + ret = -1; + } else { + *name = strdup(pwd->pw_name); + add_cachebyuuid(uuidp, *name, *type, 0); + ret = 0; + } + LOG(log_debug, logtype_afpd, + "getnamefromuuid{local}: UUID: %s -> name: %s, type:%s", + uuid_bin2string(uuidp), *name, uuidtype[(*type) & UUIDTYPESTR_MASK]); + return ret; + } else if (memcmp(uuidp, local_group_uuid, 12) == 0) { + *type = UUID_GROUP; + gid = ntohl(*(uint32_t *)(uuidp + 12)); + if ((grp = getgrgid(gid)) == NULL) { + /* not found, add negative entry to cache */ + add_cachebyuuid(uuidp, "UUID_ENOENT", UUID_ENOENT, 0); + ret = -1; + } else { + *name = strdup(grp->gr_name); + add_cachebyuuid(uuidp, *name, *type, 0); + ret = 0; } + return ret; + } #ifdef HAVE_LDAP - ret = ldap_getnamefromuuid(uuid_bin2string(uuidp), name, type); - if (ret != 0) { - LOG(log_warning, logtype_afpd, "getnamefromuuid(%s): no result from ldap_getnamefromuuid", - uuid_bin2string(uuidp)); - goto cleanup; - } - add_cachebyuuid( uuidp, *name, *type, 0); - LOG(log_debug, logtype_afpd, "getnamefromuuid{LDAP}: UUID: %s -> name: %s, type:%s", - uuid_bin2string(uuidp), *name, uuidtype[*type]); + ret = ldap_getnamefromuuid(uuid_bin2string(uuidp), name, type); +#else + ret = -1; #endif + + if (ret != 0) { + LOG(log_debug, logtype_afpd, "getnamefromuuid(%s): not found", + uuid_bin2string(uuidp)); + add_cachebyuuid(uuidp, "UUID_ENOENT", UUID_ENOENT, 0); + return -1; } -cleanup: - return ret; + add_cachebyuuid(uuidp, *name, *type, 0); + + LOG(log_debug, logtype_afpd, "getnamefromuuid{LDAP}: UUID: %s -> name: %s, type:%s", + uuid_bin2string(uuidp), *name, uuidtype[(*type) & UUIDTYPESTR_MASK]); + + return 0; }