diff options
Diffstat (limited to 'nsswitch/libwbclient')
-rw-r--r-- | nsswitch/libwbclient/wbclient.c | 53 | ||||
-rw-r--r-- | nsswitch/libwbclient/wbclient_internal.h | 3 |
2 files changed, 54 insertions, 2 deletions
diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c index cd5ffa876a..6b076ad499 100644 --- a/nsswitch/libwbclient/wbclient.c +++ b/nsswitch/libwbclient/wbclient.c @@ -147,12 +147,61 @@ const char *wbcErrorString(wbcErr error) return "unknown wbcErr value"; } +#define WBC_MAGIC (0x7a2b0e1e) + +struct wbcMemPrefix { + uint32_t magic; + void (*destructor)(void *ptr); +}; + +static size_t wbcPrefixLen(void) +{ + size_t result = sizeof(struct wbcMemPrefix); + return (result + 15) & ~15; +} + +static struct wbcMemPrefix *wbcMemToPrefix(void *ptr) +{ + return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen()); +} + +void *wbcAllocateMemory(size_t nelem, size_t elsize, + void (*destructor)(void *ptr)) +{ + struct wbcMemPrefix *result; + + if (nelem >= (2<<24)/elsize) { + /* basic protection against integer wrap */ + return NULL; + } + + result = (struct wbcMemPrefix *)calloc( + 1, nelem*elsize + wbcPrefixLen()); + if (result == NULL) { + return NULL; + } + result->magic = WBC_MAGIC; + result->destructor = destructor; + return ((char *)result) + wbcPrefixLen(); +} + /* Free library allocated memory */ void wbcFreeMemory(void *p) { - if (p) - talloc_free(p); + struct wbcMemPrefix *wbcMem; + if (p == NULL) { + return; + } + wbcMem = wbcMemToPrefix(p); + if (wbcMem->magic != WBC_MAGIC) { + talloc_free(p); + return; + } + if (wbcMem->destructor != NULL) { + wbcMem->destructor(p); + } + free(wbcMem); return; } diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h index 5ce820785e..6c59be3fef 100644 --- a/nsswitch/libwbclient/wbclient_internal.h +++ b/nsswitch/libwbclient/wbclient_internal.h @@ -32,4 +32,7 @@ wbcErr wbcRequestResponsePriv(int cmd, struct winbindd_request *request, struct winbindd_response *response); +void *wbcAllocateMemory(size_t nelem, size_t elsize, + void (*destructor)(void *ptr)); + #endif /* _WBCLIENT_INTERNAL_H */ |