]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/acl/uuid.c
Merge master
[netatalk.git] / libatalk / acl / uuid.c
index 010de4db7869701efc1b30472cbe082faf91f00a..4b9703617b18d7f2cbc122b2be2685c4e29d3230 100644 (file)
@@ -21,6 +21,9 @@
 #include <string.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
 
 #include <atalk/logger.h>
 #include <atalk/afp.h>
@@ -36,11 +39,39 @@ char *uuidtype[] = {"NULL","USER", "GROUP", "LOCAL"};
  * Public helper function
  ********************************************************/
 
+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};
+
+void localuuid_from_id(unsigned char *buf, uuidtype_t type, unsigned int id)
+{
+    uint32_t tmp;
+
+    switch (type) {
+    case UUID_GROUP:
+        memcpy(buf, local_group_uuid, 12);
+        break;
+    case UUID_USER:
+    default:
+        memcpy(buf, local_user_uuid, 12);
+        break;
+    }
+
+    tmp = htonl(id);
+    memcpy(buf + 12, &tmp, 4);
+
+    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;
@@ -74,24 +105,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(const 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++] = '-';
     }
@@ -109,10 +133,11 @@ const char *uuid_bin2string(char *uuid) {
  *   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;
+#ifdef HAVE_LDAP
     char *uuid_string = NULL;
-
+#endif
     ret = search_cachebyname( name, type, uuid);
     if (ret == 0) {
         /* found in cache */
@@ -120,29 +145,49 @@ 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) {
+                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));
+        }
+        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
@@ -152,7 +197,7 @@ static char local_user_uuid[] = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd,
  *
  * Caller must free name appropiately.
  */
-int getnamefromuuid(const uuidp_t uuidp, char **name, uuidtype_t *type) {
+int getnamefromuuid(uuidp_t uuidp, char **name, uuidtype_t *type) {
     int ret;
 
     ret = search_cachebyuuid( uuidp, name, type);
@@ -173,6 +218,7 @@ int getnamefromuuid(const uuidp_t uuidp, char **name, uuidtype_t *type) {
             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",
@@ -182,6 +228,7 @@ int getnamefromuuid(const uuidp_t uuidp, char **name, uuidtype_t *type) {
         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]);
+#endif
     }
 
 cleanup: