]> arthur.barton.de Git - netatalk.git/blob - libatalk/acl/uuid.c
Merge branch 'branch-netatalk-2-1' of ssh://netatalk.git.sourceforge.net/gitroot...
[netatalk.git] / libatalk / acl / uuid.c
1 /*
2   Copyright (c) 2008,2009 Frank Lahm <franklahm@gmail.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif /* HAVE_CONFIG_H */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23
24 #include <atalk/logger.h>
25 #include <atalk/afp.h>
26 #include <atalk/uuid.h>
27 #include <atalk/util.h>
28
29 #include "aclldap.h"
30 #include "cache.h"
31
32 char *uuidtype[] = {"NULL","USER", "GROUP"};
33
34 /********************************************************
35  * Public helper function
36  ********************************************************/
37
38 static unsigned char local_group_uuid[] = {0xab, 0xcd, 0xef,
39                                            0xab, 0xcd, 0xef,
40                                            0xab, 0xcd, 0xef, 
41                                            0xab, 0xcd, 0xef};
42
43 static unsigned char local_user_uuid[] = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd,
44                                           0xcc, 0xcc, 0xbb, 0xbb, 0xaa, 0xaa};
45
46 void localuuid_from_id(unsigned char *buf, uuidtype_t type, unsigned int id)
47 {
48     uint32_t tmp;
49
50     switch (type) {
51     case UUID_GROUP:
52         memcpy(buf, local_group_uuid, 12);
53         break;
54     case UUID_USER:
55     default:
56         memcpy(buf, local_user_uuid, 12);
57         break;
58     }
59
60     tmp = htonl(id);
61     memcpy(buf + 12, &tmp, 4);
62
63     return;
64 }
65
66 /* 
67  * convert ascii string that can include dashes to binary uuid.
68  * caller must provide a buffer.
69  */
70 void uuid_string2bin( const char *uuidstring, uuidp_t uuid) {
71     int nibble = 1;
72     int i = 0;
73     unsigned char c, val = 0;
74
75     while (*uuidstring) {
76         c = *uuidstring;
77         if (c == '-') {
78             uuidstring++;
79             continue;
80         }
81         else if (c <= '9')      /* 0-9 */
82             c -= '0';
83         else if (c <= 'F')  /* A-F */
84             c -= 'A' - 10;
85         else if (c <= 'f')      /* a-f */
86             c-= 'a' - 10;
87
88         if (nibble)
89             val = c * 16;
90         else
91             uuid[i++] = val + c;
92
93         nibble ^= 1;
94         uuidstring++;
95     }
96
97 }
98
99 /* 
100  * convert 16 byte binary uuid to neat ascii represantation including dashes
101  * string is allocated and pointer returned. caller must freee.
102  */
103 int uuid_bin2string( uuidp_t uuid, char **uuidstring) {
104     char ascii[16] = { "0123456789ABCDEF" };
105     int nibble = 1;
106     int i = 0;
107     unsigned char c;
108     char *s;
109
110     *uuidstring = calloc(1, UUID_STRINGSIZE + 1);
111     if (*uuidstring == NULL) {
112         LOG(log_error, logtype_default, "uuid_bin2string: %s: error calloc'ing",strerror(errno));
113         return -1;
114     }
115     s = *uuidstring;
116
117     while (i < UUID_STRINGSIZE) {
118         c = *uuid;
119         if (nibble)
120             c = c >> 4;
121         else {
122             c &= 0x0f;
123             uuid++;
124         }
125         s[i] = ascii[c];
126         nibble ^= 1;
127         i++;
128         if (i==8 || i==13 || i==18 || i==23)
129             s[i++] = '-';
130     }
131     return 0;
132 }
133
134 /********************************************************
135  * Interface
136  ********************************************************/
137
138 /*
139  *   name: give me his name
140  *   type: and type (UUID_USER or UUID_GROUP)
141  *   uuid: pointer to uuid_t storage that the caller must provide
142  * returns 0 on success !=0 on errror
143  */  
144 int getuuidfromname( const char *name, uuidtype_t type, uuidp_t uuid) {
145     int ret = 0;
146     char *uuid_string = NULL;
147
148     ret = search_cachebyname( name, type, uuid);
149     if (ret == 0) {     /* found in cache */
150 #ifdef DEBUG
151         uuid_bin2string( uuid, &uuid_string);
152         LOG(log_debug, logtype_afpd, "getuuidfromname{cache}: name: %s, type: %s -> UUID: %s",
153             name, uuidtype[type], uuid_string);
154 #else
155         LOG(log_debug, logtype_afpd, "getuuidfromname{cache}: name: %s, type: %s",
156             name, uuidtype[type]);
157 #endif
158     } else  {                   /* if not found in cache */
159         ret = ldap_getuuidfromname( name, type, &uuid_string);
160         if (ret != 0) {
161             LOG(log_info, logtype_afpd, "getuuidfromname: no result from ldap_getuuidfromname");
162             goto cleanup;
163         }
164         uuid_string2bin( uuid_string, uuid);
165         add_cachebyname( name, uuid, type, 0);
166         LOG(log_debug, logtype_afpd, "getuuidfromname{LDAP}: name: %s, type: %s -> UUID: %s",name, uuidtype[type], uuid_string);
167     }
168
169 cleanup:
170     free(uuid_string);
171     return ret;
172 }
173
174 /* 
175  * uuidp: pointer to a uuid
176  * name: returns allocated buffer from ldap_getnamefromuuid
177  * type: returns USER or GROUP
178  * return 0 on success !=0 on errror
179  *
180  * Caller must free name appropiately.
181  */
182 int getnamefromuuid( uuidp_t uuidp, char **name, uuidtype_t *type) {
183     int ret;
184     char *uuid_string = NULL;
185
186     ret = search_cachebyuuid( uuidp, name, type);
187     if (ret == 0) {     /* found in cache */
188 #ifdef DEBUG
189         uuid_bin2string( uuidp, &uuid_string);
190         LOG(log_debug9, logtype_afpd, "getnamefromuuid{cache}: UUID: %s -> name: %s, type:%s",
191             uuid_string, *name, uuidtype[*type]);
192         free(uuid_string);
193         uuid_string = NULL;
194 #endif
195     } else  {                   /* if not found in cache */
196         uuid_bin2string( uuidp, &uuid_string);
197         ret = ldap_getnamefromuuid( uuid_string, name, type);
198         if (ret != 0) {
199             LOG(log_warning, logtype_afpd, "getnamefromuuid(%s): no result from ldap_getnamefromuuid",
200                 uuid_string);
201             goto cleanup;
202         }
203         add_cachebyuuid( uuidp, *name, *type, 0);
204         LOG(log_debug, logtype_afpd, "getnamefromuuid{LDAP}: UUID: %s -> name: %s, type:%s",
205             uuid_string, *name, uuidtype[*type]);
206     }
207
208 cleanup:
209     free(uuid_string);
210     return ret;
211 }