From f2a04a0ccb7276dcd23efeade59368540c6570b2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 Apr 2010 22:10:22 +0200 Subject: libwbclient: Add wbcAllocateMemory() This prepares for removing libwbclient's talloc dependency. It is a non-hierarchical "talloc-lite" that has destructors. It is necessary because we have the catch-call wbcFreeMemory call. Individual wbcFreeXXX calls for the different structures wbclient returns would have made this easier, but wbcFreeMemory is the API we have to live with. --- nsswitch/libwbclient/wbclient.c | 53 ++++++++++++++++++++++++++++++-- nsswitch/libwbclient/wbclient_internal.h | 3 ++ 2 files changed, 54 insertions(+), 2 deletions(-) (limited to 'nsswitch/libwbclient') 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 */ -- cgit