diff options
Diffstat (limited to 'source4/auth')
-rw-r--r-- | source4/auth/gensec/gensec.c | 77 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.h | 1 |
2 files changed, 78 insertions, 0 deletions
diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index f93cee788e..531c30005b 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -904,6 +904,83 @@ _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_ return gensec_security->ops->update(gensec_security, out_mem_ctx, in, out); } +struct gensec_update_request { + struct gensec_security *gensec_security; + DATA_BLOB in; + DATA_BLOB out; + NTSTATUS status; + void (*callback)(struct gensec_update_request *req, void *private_data); + void *private_data; +}; + +static void gensec_update_async_timed_handler(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct gensec_update_request *req = talloc_get_type(ptr, struct gensec_update_request); + req->status = req->gensec_security->ops->update(req->gensec_security, req, req->in, &req->out); + req->callback(req, req->private_data); +} + +/** + * Next state function for the GENSEC state machine async version + * + * @param gensec_security GENSEC State + * @param in The request, as a DATA_BLOB + * @param callback The function that will be called when the operation is + * finished, it should return gensec_update_recv() to get output + * @param private_data A private pointer that will be passed to the callback function + */ + +_PUBLIC_ void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in, + void (*callback)(struct gensec_update_request *req, void *private_data), + void *private_data) +{ + struct gensec_update_request *req = NULL; + struct timed_event *te = NULL; + + req = talloc(gensec_security, struct gensec_update_request); + if (!req) goto failed; + req->gensec_security = gensec_security; + req->in = in; + req->out = data_blob(NULL, 0); + req->callback = callback; + req->private_data = private_data; + + te = event_add_timed(gensec_security->event_ctx, req, + timeval_zero(), + gensec_update_async_timed_handler, req); + if (!te) goto failed; + + return; + +failed: + talloc_free(req); + callback(NULL, private_data); +} + +/** + * Next state function for the GENSEC state machine + * + * @param req GENSEC update request state + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ +_PUBLIC_ NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out) +{ + NTSTATUS status; + + NT_STATUS_HAVE_NO_MEMORY(req); + + *out = req->out; + talloc_steal(out_mem_ctx, out->data); + status = req->status; + + talloc_free(req); + return status; +} + /** * Set the requirement for a certain feature on the connection * diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index d21008f034..be5e900188 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -33,6 +33,7 @@ #define GENSEC_OID_KERBEROS5_USER2USER "1 2 840 113554 1 2 2 3" struct gensec_security; +struct gensec_update_request; struct gensec_target { const char *principal; const char *hostname; |