]> arthur.barton.de Git - netatalk.git/blob - libatalk/acl/uuid.c
Code cleanup while hunting a memory leak
[netatalk.git] / libatalk / acl / uuid.c
1 /*
2   $Id: uuid.c,v 1.3 2009-11-27 16:33:49 franklahm Exp $
3   Copyright (c) 2008,2009 Frank Lahm <franklahm@gmail.com>
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 */
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif /* HAVE_CONFIG_H */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24
25 #include <atalk/logger.h>
26 #include <atalk/afp.h>
27 #include <atalk/uuid.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_error, 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: give me a pointer to a uuid
148  *   name: and I'll allocate a buf with his name and store a pointer to buf
149  *   type: returns USER or GROUP
150  * return 0 on success !=0 on errror
151  */
152 int getnamefromuuid( uuidp_t uuidp, char **name, uuidtype_t *type) {
153     int ret;
154     char *uuid_string = NULL;
155
156     ret = search_cachebyuuid( uuidp, name, type);
157     if (ret == 0) {     /* found in cache */
158 #ifdef DEBUG
159         uuid_bin2string( uuidp, &uuid_string);
160         LOG(log_debug9, logtype_afpd, "getnamefromuuid{cache}: UUID: %s -> name: %s, type:%s", uuid_string, *name, uuidtype[*type]);
161         free(uuid_string);
162         uuid_string = NULL;
163 #endif
164     } else  {                   /* if not found in cache */
165         uuid_bin2string( uuidp, &uuid_string);
166         ret = ldap_getnamefromuuid( uuid_string, name, type);
167         if (ret != 0) {
168             LOG(log_error, logtype_afpd, "getnamefromuuid: no result from ldap_getnamefromuuid");
169             goto cleanup;
170         }
171         add_cachebyuuid( uuidp, *name, *type, 0);
172         LOG(log_debug, logtype_afpd, "getnamefromuuid{LDAP}: UUID: %s -> name: %s, type:%s",uuid_string, *name, uuidtype[*type]);
173     }
174
175 cleanup:
176     free(uuid_string);
177     return ret;
178 }