X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=libatalk%2Facl%2Fuuid.c;h=074d9deb8a76c1da0343292b6250d940ee09d5c2;hp=8943fd82817bb2b862ed9b581ae67a977bcc6133;hb=64c01c136e708085840814c92ff7cf829a794317;hpb=e671cdc26165d0f87a24c382dbed1a3c19230caf diff --git a/libatalk/acl/uuid.c b/libatalk/acl/uuid.c index 8943fd82..074d9deb 100644 --- a/libatalk/acl/uuid.c +++ b/libatalk/acl/uuid.c @@ -20,6 +20,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -29,7 +33,7 @@ #include "aclldap.h" #include "cache.h" -char *uuidtype[] = {"NULL","USER", "GROUP"}; +char *uuidtype[] = {"NULL","USER", "GROUP", "LOCAL"}; /******************************************************** * Public helper function @@ -96,39 +100,27 @@ void uuid_string2bin( const char *uuidstring, uuidp_t uuid) { } -/* - * convert 16 byte binary uuid to neat ascii represantation including dashes - * string is allocated and pointer returned. caller must freee. +/*! + * Convert 16 byte binary uuid to neat ascii represantation including dashes. + * + * Returns pointer to static buffer. */ -int uuid_bin2string( uuidp_t uuid, char **uuidstring) { - char ascii[16] = { "0123456789ABCDEF" }; - int nibble = 1; +const char *uuid_bin2string(unsigned char *uuid) { + static char uuidstring[UUID_STRINGSIZE + 1]; + int i = 0; unsigned char c; - char *s; - - *uuidstring = calloc(1, UUID_STRINGSIZE + 1); - if (*uuidstring == NULL) { - LOG(log_error, logtype_default, "uuid_bin2string: %s: error calloc'ing",strerror(errno)); - return -1; - } - s = *uuidstring; while (i < UUID_STRINGSIZE) { c = *uuid; - if (nibble) - c = c >> 4; - else { - c &= 0x0f; - uuid++; - } - s[i] = ascii[c]; - nibble ^= 1; - i++; + uuid++; + sprintf(uuidstring + i, "%02X", c); + i += 2; if (i==8 || i==13 || i==18 || i==23) - s[i++] = '-'; + uuidstring[i++] = '-'; } - return 0; + uuidstring[i] = 0; + return uuidstring; } /******************************************************** @@ -143,69 +135,102 @@ int uuid_bin2string( uuidp_t uuid, char **uuidstring) { */ 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 */ -#ifdef DEBUG - uuid_bin2string( uuid, &uuid_string); + if (ret == 0) { + /* found in cache */ LOG(log_debug, logtype_afpd, "getuuidfromname{cache}: name: %s, type: %s -> UUID: %s", - name, uuidtype[type], uuid_string); -#else - LOG(log_debug, logtype_afpd, "getuuidfromname{cache}: name: %s, type: %s", - name, uuidtype[type]); + name, uuidtype[type], uuid_bin2string(uuid)); + } 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)); + } else { + LOG(log_debug, logtype_afpd, "getuuidfromname(\"%s\",t:%u): no result from ldap search", + name, type); + } #endif - } else { /* if not found in cache */ - ret = ldap_getuuidfromname( name, type, &uuid_string); if (ret != 0) { - LOG(log_info, logtype_afpd, "getuuidfromname: no result from ldap_getuuidfromname"); - goto cleanup; + /* Build a local UUID */ + if (type == UUID_USER) { + struct passwd *pwd; + if ((pwd = getpwnam(name)) == NULL) { + LOG(log_error, logtype_afpd, "getuuidfromname(\"%s\",t:%u): unknown user", + name, uuidtype[type]); + goto cleanup; + } + 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; + } + 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)); } - uuid_string2bin( uuid_string, 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: - free(uuid_string); +#ifdef HAVE_LDAP + if (uuid_string) free(uuid_string); +#endif return ret; } -/* + +/* * uuidp: pointer to a uuid * name: returns allocated buffer from ldap_getnamefromuuid - * type: returns USER or GROUP + * type: returns USER, GROUP or LOCAL * return 0 on success !=0 on errror * * Caller must free name appropiately. */ -int getnamefromuuid( uuidp_t uuidp, char **name, uuidtype_t *type) { +int getnamefromuuid(const uuidp_t uuidp, char **name, uuidtype_t *type) { int ret; - char *uuid_string = NULL; ret = search_cachebyuuid( uuidp, name, type); - if (ret == 0) { /* found in cache */ -#ifdef DEBUG - uuid_bin2string( uuidp, &uuid_string); + if (ret == 0) { + /* found in cache */ LOG(log_debug9, logtype_afpd, "getnamefromuuid{cache}: UUID: %s -> name: %s, type:%s", - uuid_string, *name, uuidtype[*type]); - free(uuid_string); - uuid_string = NULL; -#endif - } else { /* if not found in cache */ - uuid_bin2string( uuidp, &uuid_string); - ret = ldap_getnamefromuuid( uuid_string, name, type); + 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; + } + +#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_string); + 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_string, *name, uuidtype[*type]); + uuid_bin2string(uuidp), *name, uuidtype[*type]); +#endif } cleanup: - free(uuid_string); return ret; }