]> arthur.barton.de Git - netatalk.git/blob - libatalk/acl/uuid.c
better error logging
[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 /* 
39  * convert ascii string that can include dashes to binary uuid.
40  * caller must provide a buffer.
41  */
42 void uuid_string2bin( const char *uuidstring, uuidp_t uuid) {
43     int nibble = 1;
44     int i = 0;
45     unsigned char c, val = 0;
46
47     while (*uuidstring) {
48         c = *uuidstring;
49         if (c == '-') {
50             uuidstring++;
51             continue;
52         }
53         else if (c <= '9')      /* 0-9 */
54             c -= '0';
55         else if (c <= 'F')  /* A-F */
56             c -= 'A' - 10;
57         else if (c <= 'f')      /* a-f */
58             c-= 'a' - 10;
59
60         if (nibble)
61             val = c * 16;
62         else
63             uuid[i++] = val + c;
64
65         nibble ^= 1;
66         uuidstring++;
67     }
68
69 }
70
71 /* 
72  * convert 16 byte binary uuid to neat ascii represantation including dashes
73  * string is allocated and pointer returned. caller must freee.
74  */
75 int uuid_bin2string( uuidp_t uuid, char **uuidstring) {
76     char ascii[16] = { "0123456789ABCDEF" };
77     int nibble = 1;
78     int i = 0;
79     unsigned char c;
80     char *s;
81
82     *uuidstring = calloc(1, UUID_STRINGSIZE + 1);
83     if (*uuidstring == NULL) {
84         LOG(log_error, logtype_default, "uuid_bin2string: %s: error calloc'ing",strerror(errno));
85         return -1;
86     }
87     s = *uuidstring;
88
89     while (i < UUID_STRINGSIZE) {
90         c = *uuid;
91         if (nibble)
92             c = c >> 4;
93         else {
94             c &= 0x0f;
95             uuid++;
96         }
97         s[i] = ascii[c];
98         nibble ^= 1;
99         i++;
100         if (i==8 || i==13 || i==18 || i==23)
101             s[i++] = '-';
102     }
103     return 0;
104 }
105
106 /********************************************************
107  * Interface
108  ********************************************************/
109
110 /*
111  *   name: give me his name
112  *   type: and type (UUID_USER or UUID_GROUP)
113  *   uuid: pointer to uuid_t storage that the caller must provide
114  * returns 0 on success !=0 on errror
115  */  
116 int getuuidfromname( const char *name, uuidtype_t type, uuidp_t uuid) {
117     int ret = 0;
118     char *uuid_string = NULL;
119
120     ret = search_cachebyname( name, type, uuid);
121     if (ret == 0) {     /* found in cache */
122 #ifdef DEBUG
123         uuid_bin2string( uuid, &uuid_string);
124         LOG(log_debug, logtype_afpd, "getuuidfromname{cache}: name: %s, type: %s -> UUID: %s",
125             name, uuidtype[type], uuid_string);
126 #else
127         LOG(log_debug, logtype_afpd, "getuuidfromname{cache}: name: %s, type: %s",
128             name, uuidtype[type]);
129 #endif
130     } else  {                   /* if not found in cache */
131         ret = ldap_getuuidfromname( name, type, &uuid_string);
132         if (ret != 0) {
133             LOG(log_info, logtype_afpd, "getuuidfromname: no result from ldap_getuuidfromname");
134             goto cleanup;
135         }
136         uuid_string2bin( uuid_string, uuid);
137         add_cachebyname( name, uuid, type, 0);
138         LOG(log_debug, logtype_afpd, "getuuidfromname{LDAP}: name: %s, type: %s -> UUID: %s",name, uuidtype[type], uuid_string);
139     }
140
141 cleanup:
142     free(uuid_string);
143     return ret;
144 }
145
146 /* 
147  * uuidp: pointer to a uuid
148  * name: returns allocated buffer from ldap_getnamefromuuid
149  * type: returns USER or GROUP
150  * return 0 on success !=0 on errror
151  *
152  * Caller must free name appropiately.
153  */
154 int getnamefromuuid( uuidp_t uuidp, char **name, uuidtype_t *type) {
155     int ret;
156     char *uuid_string = NULL;
157
158     ret = search_cachebyuuid( uuidp, name, type);
159     if (ret == 0) {     /* found in cache */
160 #ifdef DEBUG
161         uuid_bin2string( uuidp, &uuid_string);
162         LOG(log_debug9, logtype_afpd, "getnamefromuuid{cache}: UUID: %s -> name: %s, type:%s",
163             uuid_string, *name, uuidtype[*type]);
164         free(uuid_string);
165         uuid_string = NULL;
166 #endif
167     } else  {                   /* if not found in cache */
168         uuid_bin2string( uuidp, &uuid_string);
169         ret = ldap_getnamefromuuid( uuid_string, name, type);
170         if (ret != 0) {
171             LOG(log_warning, logtype_afpd, "getnamefromuuid(%s): no result from ldap_getnamefromuuid",
172                 uuid_string);
173             goto cleanup;
174         }
175         add_cachebyuuid( uuidp, *name, *type, 0);
176         LOG(log_debug, logtype_afpd, "getnamefromuuid{LDAP}: UUID: %s -> name: %s, type:%s",
177             uuid_string, *name, uuidtype[*type]);
178     }
179
180 cleanup:
181     free(uuid_string);
182     return ret;
183 }