]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/acl/uuid.c
afpd.conf.tmpl: Merge remote-tracking branch 'remotes/origin/branch-netatalk-2-1'
[netatalk.git] / libatalk / acl / uuid.c
index 010de4db7869701efc1b30472cbe082faf91f00a..074d9deb8a76c1da0343292b6250d940ee09d5c2 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,6 +39,34 @@ 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.
@@ -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(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++] = '-';
     }
@@ -111,8 +135,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 +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
@@ -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: