summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nsswitch/libwbclient/wbclient.c53
-rw-r--r--nsswitch/libwbclient/wbclient_internal.h3
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 */