summaryrefslogtreecommitdiff
path: root/nsswitch/libwbclient
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2010-04-06 22:10:22 +0200
committerVolker Lendecke <vl@samba.org>2010-04-19 14:27:16 +0200
commitf2a04a0ccb7276dcd23efeade59368540c6570b2 (patch)
treef9111fc59545f07df81cf68a332714251aa069a8 /nsswitch/libwbclient
parent456351cdb184f59374cecec8d7c44add29b986dd (diff)
downloadsamba-f2a04a0ccb7276dcd23efeade59368540c6570b2.tar.gz
samba-f2a04a0ccb7276dcd23efeade59368540c6570b2.tar.bz2
samba-f2a04a0ccb7276dcd23efeade59368540c6570b2.zip
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.
Diffstat (limited to 'nsswitch/libwbclient')
-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 */