Add tldap_context_[gs]etattr
authorVolker Lendecke <vl@samba.org>
Fri, 19 Jun 2009 09:45:01 +0000 (11:45 +0200)
committerVolker Lendecke <vl@samba.org>
Fri, 19 Jun 2009 12:28:22 +0000 (14:28 +0200)
This adds the ability to attach extended information to a tldap_context. This
will become useful once we start to do automatic reconnects for example, a
callback function might want attach a pointer to credentials so that it can
rebind.

The initial user of this will be a cached rootdse, so that things like the
ability to do paged searches can be cached.

source3/include/tldap.h
source3/lib/tldap.c

index d57484c5f81caaab01f163d57b1b66a807899cb8..8e5664241ef228b9f1fc26971170fae12f49a5e3 100644 (file)
@@ -46,6 +46,9 @@ struct tldap_mod {
 };
 
 struct tldap_context *tldap_context_create(TALLOC_CTX *mem_ctx, int fd);
+bool tldap_context_setattr(struct tldap_context *ld,
+                          const char *name, const void *pptr);
+void *tldap_context_getattr(struct tldap_context *ld, const char *name);
 
 struct tevent_req *tldap_sasl_bind_send(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *ev,
index c70b8ca95d1222093b36099293ce3b97d529ff3e..10766fe34f522ff6d7cf605ab984e9e821fb8182 100644 (file)
@@ -44,6 +44,11 @@ static bool tevent_req_is_ldap_error(struct tevent_req *req, int *perr)
        return true;
 }
 
+struct tldap_ctx_attribute {
+       char *name;
+       void *ptr;
+};
+
 struct tldap_context {
        int ld_version;
        int ld_deref;
@@ -64,6 +69,8 @@ struct tldap_context {
        void (*log_fn)(void *context, enum tldap_debug_level level,
                       const char *fmt, va_list ap);
        void *log_private;
+
+       struct tldap_ctx_attribute *ctx_attrs;
 };
 
 struct tldap_message {
@@ -134,6 +141,77 @@ struct tldap_context *tldap_context_create(TALLOC_CTX *mem_ctx, int fd)
        return ctx;
 }
 
+static struct tldap_ctx_attribute *tldap_context_findattr(
+       struct tldap_context *ld, const char *name)
+{
+       int i, num_attrs;
+
+       num_attrs = talloc_array_length(ld->ctx_attrs);
+
+       for (i=0; i<num_attrs; i++) {
+               if (strcmp(ld->ctx_attrs[i].name, name) == 0) {
+                       return &ld->ctx_attrs[i];
+               }
+       }
+       return NULL;
+}
+
+bool tldap_context_setattr(struct tldap_context *ld,
+                          const char *name, const void *_pptr)
+{
+       struct tldap_ctx_attribute *tmp, *attr;
+       char *tmpname;
+       int num_attrs;
+       void **pptr = (void **)_pptr;
+
+       attr = tldap_context_findattr(ld, name);
+       if (attr != NULL) {
+               /*
+                * We don't actually delete attrs, we don't expect tons of
+                * attributes being shuffled around.
+                */
+               TALLOC_FREE(attr->ptr);
+               if (*pptr != NULL) {
+                       attr->ptr = talloc_move(ld->ctx_attrs, pptr);
+                       *pptr = NULL;
+               }
+               return true;
+       }
+
+       tmpname = talloc_strdup(ld, name);
+       if (tmpname == NULL) {
+               return false;
+       }
+
+       num_attrs = talloc_array_length(ld->ctx_attrs);
+
+       tmp = talloc_realloc(ld, ld->ctx_attrs, struct tldap_ctx_attribute,
+                            num_attrs+1);
+       if (tmp == NULL) {
+               TALLOC_FREE(tmpname);
+               return false;
+       }
+       tmp[num_attrs].name = talloc_move(tmp, &tmpname);
+       if (*pptr != NULL) {
+               tmp[num_attrs].ptr = talloc_move(tmp, pptr);
+       } else {
+               tmp[num_attrs].ptr = NULL;
+       }
+       *pptr = NULL;
+       ld->ctx_attrs = tmp;
+       return true;
+}
+
+void *tldap_context_getattr(struct tldap_context *ld, const char *name)
+{
+       struct tldap_ctx_attribute *attr = tldap_context_findattr(ld, name);
+
+       if (attr == NULL) {
+               return NULL;
+       }
+       return attr->ptr;
+}
+
 struct read_ldap_state {
        uint8_t *buf;
        bool done;