[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Freeipa-devel] [PATCHES] added chpass target to proxy and LDAP backend



Hi,

the included patches will add the chpass target to the proxy and LDAP
backend (one of them will add the access target to then proxy backend,
too). While the proxy targets are simply calls to the old pam handler,
the LDAP chpass target uses the latest scheme pushed by Simo yesterday.
Simo can you please check if I got it right?

bye,
Sumit 
>From 5e8ed566296d5390d51def73f041c9bd9f510995 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose redhat com>
Date: Thu, 16 Jul 2009 16:40:29 +0200
Subject: [PATCH 1/2] add handling of the new backend targets to proxy backend

---
 server/providers/proxy.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index aa5b1c9..ddfbe39 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -2069,6 +2069,18 @@ struct bet_ops proxy_auth_ops = {
     .finalize = proxy_auth_shutdown
 };
 
+struct bet_ops proxy_access_ops = {
+    .check_online = proxy_check_online,
+    .handler = proxy_pam_handler,
+    .finalize = proxy_auth_shutdown
+};
+
+struct bet_ops proxy_chpass_ops = {
+    .check_online = proxy_check_online,
+    .handler = proxy_pam_handler,
+    .finalize = proxy_auth_shutdown
+};
+
 static void *proxy_dlsym(void *handle, const char *functemp, char *libname)
 {
     char *funcname;
@@ -2238,3 +2250,21 @@ done:
     }
     return ret;
 }
+
+int sssm_proxy_access_init(struct be_ctx *bectx,
+                           struct bet_ops **ops, void **pvt_data)
+{
+    int ret;
+    ret = sssm_proxy_auth_init(bectx, ops, pvt_data);
+    *ops = &proxy_access_ops;
+    return ret;
+}
+
+int sssm_proxy_chpass_init(struct be_ctx *bectx,
+                           struct bet_ops **ops, void **pvt_data)
+{
+    int ret;
+    ret = sssm_proxy_auth_init(bectx, ops, pvt_data);
+    *ops = &proxy_chpass_ops;
+    return ret;
+}
-- 
1.6.2.5

>From 4db372c4e0ccbb4e06864d56da9e28a62fec3de9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose redhat com>
Date: Mon, 20 Jul 2009 17:27:02 +0200
Subject: [PATCH 2/2] added LDAP change password backend target

---
 server/providers/data_provider_be.c |    8 ++-
 server/providers/ldap/ldap_auth.c   |  168 +++++++++++++++++++++++++++++++++++
 server/providers/ldap/sdap_async.c  |  137 ++++++++++++++++++++++++++++
 server/providers/ldap/sdap_async.h  |    8 ++
 4 files changed, 319 insertions(+), 2 deletions(-)

diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 5cd5994..2e0c1cf 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -631,8 +631,10 @@ static int be_pam_handler(DBusMessage *message, struct sbus_conn_ctx *sconn)
     }
 
     be_req = talloc_zero(ctx, struct be_req);
-    if (!be_req)
+    if (!be_req) {
+        DEBUG(7, ("talloc_zero failed.\n"));
         goto done;
+    }
 
     be_req->be_ctx = ctx;
     be_req->fn = be_pam_handler_callback;
@@ -640,8 +642,10 @@ static int be_pam_handler(DBusMessage *message, struct sbus_conn_ctx *sconn)
     be_req->req_data = pd;
 
     ret = be_file_request(ctx, ctx->bet_info[target].bet_ops->handler, be_req);
-    if (ret != EOK)
+    if (ret != EOK) {
+        DEBUG(7, ("be_file_request failed.\n"));
         goto done;
+    }
 
     return EOK;
 
diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c
index 2c53032..78f893e 100644
--- a/server/providers/ldap/ldap_auth.c
+++ b/server/providers/ldap/ldap_auth.c
@@ -300,7 +300,159 @@ int auth_recv(struct tevent_req *req, enum sdap_result *result)
     return EOK;
 }
 
+int auth4chpass_recv(struct tevent_req *req, enum sdap_result *result,
+                     TALLOC_CTX *memctx, struct sdap_handle **sh, char **dn)
+{
+    struct auth_state *state = tevent_req_data(req, struct auth_state);
+    enum tevent_req_state tstate;
+    uint64_t err;
+
+    if (tevent_req_is_error(req, &tstate, &err)) {
+        *result = SDAP_ERROR;
+        return err;
+    }
+
+    *sh = talloc_steal(memctx, state->sh);
+    if (!*sh) return ENOMEM;
+
+    *dn = talloc_steal(memctx, state->dn);
+    if (!*dn) return ENOMEM;
+
+    *result = state->result;
+    return EOK;
+}
+
+/* ==Perform-Password-Change===================== */
+
+struct sdap_pam_chpass_state {
+    struct be_req *breq;
+    struct pam_data *pd;
+    const char *username;
+    char *dn;
+    char *password;
+    char *new_password;
+    struct sdap_handle *sh;
+};
+
+static void sdap_auth4chpass_done(struct tevent_req *req);
+static void sdap_pam_chpass_done(struct tevent_req *req);
+static void sdap_pam_auth_reply(struct be_req *breq, int result);
 
+static void sdap_pam_chpass_send(struct be_req *breq)
+{
+    struct sdap_pam_chpass_state *state;
+    struct sdap_auth_ctx *ctx;
+    struct tevent_req *subreq;
+    struct pam_data *pd;
+
+    ctx = talloc_get_type(breq->be_ctx->bet_info[BET_CHPASS].pvt_bet_data,
+                          struct sdap_auth_ctx);
+    pd = talloc_get_type(breq->req_data, struct pam_data);
+
+    DEBUG(2, ("starting password change request for user [%s].\n", pd->user));
+
+    pd->pam_status = PAM_SYSTEM_ERR;
+
+    if (pd->cmd != SSS_PAM_CHAUTHTOK) {
+        DEBUG(2, ("chpass target was called by wrong pam command.\n"));
+        goto done;
+    }
+
+    state = talloc_zero(breq, struct sdap_pam_chpass_state);
+    if (!state) goto done;
+
+    state->breq = breq;
+    state->pd = pd;
+    state->username = pd->user;
+    state->password = talloc_strndup(state,
+                                     (char *)pd->authtok, pd->authtok_size);
+    if (!state->password) goto done;
+    talloc_set_destructor((TALLOC_CTX *)state->password,
+                          password_destructor);
+    state->new_password = talloc_strndup(state,
+                                         (char *)pd->newauthtok,
+                                         pd->newauthtok_size);
+    if (!state->new_password) goto done;
+    talloc_set_destructor((TALLOC_CTX *)state->new_password,
+                          password_destructor);
+
+    subreq = auth_send(breq, breq->be_ctx->ev,
+                       ctx, state->username, state->password);
+    if (!subreq) goto done;
+
+    tevent_req_set_callback(subreq, sdap_auth4chpass_done, state);
+    return;
+done:
+    sdap_pam_auth_reply(breq, pd->pam_status);
+}
+
+static void sdap_auth4chpass_done(struct tevent_req *req)
+{
+    struct sdap_pam_chpass_state *state =
+                    tevent_req_callback_data(req, struct sdap_pam_chpass_state);
+    struct tevent_req *subreq;
+    enum sdap_result result;
+    int ret;
+
+    ret = auth4chpass_recv(req, &result, state, &state->sh, &state->dn);
+    talloc_zfree(req);
+    if (ret) {
+        state->pd->pam_status = PAM_SYSTEM_ERR;
+        goto done;
+    }
+
+
+    switch (result) {
+    case SDAP_AUTH_SUCCESS:
+        DEBUG(7, ("user [%s] successfully authenticated.\n", state->dn));
+        subreq = sdap_exop_modify_passwd_send(state,
+                                              state->breq->be_ctx->ev,
+                                              state->sh,
+                                              state->dn,
+                                              state->password,
+                                              state->new_password);
+
+        if (!subreq) {
+            DEBUG(2, ("Failed to change password for %s\n", state->username));
+            goto done;
+        }
+
+        tevent_req_set_callback(subreq, sdap_pam_chpass_done, state);
+        return;
+        break;
+    default:
+        state->pd->pam_status = PAM_SYSTEM_ERR;
+    }
+
+done:
+    sdap_pam_auth_reply(state->breq, state->pd->pam_status);
+}
+
+static void sdap_pam_chpass_done(struct tevent_req *req)
+{
+    struct sdap_pam_chpass_state *state =
+                    tevent_req_callback_data(req, struct sdap_pam_chpass_state);
+    enum sdap_result result;
+    int ret;
+
+    ret = sdap_exop_modify_passwd_recv(req, &result);
+    talloc_zfree(req);
+    if (ret) {
+        state->pd->pam_status = PAM_SYSTEM_ERR;
+        goto done;
+    }
+
+    switch (result) {
+    case SDAP_SUCCESS:
+        state->pd->pam_status = PAM_SUCCESS;
+        break;
+    default:
+        state->pd->pam_status = PAM_SYSTEM_ERR;
+    }
+
+done:
+    sdap_pam_auth_reply(state->breq, state->pd->pam_status);
+}
 /* ==Perform-User-Authentication-and-Password-Caching===================== */
 
 struct sdap_pam_auth_state {
@@ -453,6 +605,12 @@ struct bet_ops sdap_auth_ops = {
     .finalize = sdap_shutdown
 };
 
+struct bet_ops sdap_chpass_ops = {
+    .check_online = NULL,
+    .handler = sdap_pam_chpass_send,
+    .finalize = sdap_shutdown
+};
+
 int sssm_ldap_auth_init(struct be_ctx *bectx,
                         struct bet_ops **ops,
                         void **pvt_data)
@@ -514,3 +672,13 @@ done:
     }
     return ret;
 }
+
+int sssm_ldap_chpass_init(struct be_ctx *bectx,
+                          struct bet_ops **ops,
+                          void **pvt_data)
+{
+    int ret;
+    ret = sssm_ldap_auth_init(bectx, ops, pvt_data);
+    *ops = &sdap_chpass_ops;
+    return ret;
+}
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index 57234e3..01142ca 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -1639,3 +1639,140 @@ int sdap_get_initgr_recv(struct tevent_req *req)
     return EOK;
 }
 
+struct sdap_exop_modify_passwd_state {
+    struct sdap_handle *sh;
+    int msgid;
+    char *user_dn;
+    char *password;
+    char *new_password;
+    int result;
+    struct sdap_msg *reply;
+    BerElement *ber;
+    struct berval *bv;
+};
+
+static void sdap_exop_modify_passwd_done(void *pvt, int error, struct sdap_msg *reply);
+
+struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
+                                           struct tevent_context *ev,
+                                           struct sdap_handle *sh,
+                                           char *user_dn,
+                                           char *password,
+                                           char *new_password)
+{
+    struct tevent_req *req = NULL;
+    struct sdap_exop_modify_passwd_state *state;
+    int ret;
+
+    req = tevent_req_create(memctx, &state,
+                            struct sdap_exop_modify_passwd_state);
+    if (!req) return NULL;
+
+    state->sh = sh;
+
+    state->reply = talloc(state, struct sdap_msg);
+    if (state->reply == NULL) {
+        DEBUG(7, ("talloc failed.\n"));
+        talloc_zfree(req);
+        return NULL;
+    }
+
+    state->ber = ber_alloc_t( LBER_USE_DER );
+    if (state->ber == NULL) {
+        DEBUG(7, ("ber_alloc_t failed.\n"));
+        talloc_zfree(req);
+        return NULL;
+    }
+
+    ret = ber_printf( state->ber, "{tststs}", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
+                     user_dn,
+                     LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, password,
+                     LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, new_password);
+    if (ret == -1) {
+        DEBUG(1, ("ber_printf failed.\n"));
+        talloc_zfree(req);
+        return NULL;
+    }
+
+    ret = ber_flatten(state->ber, &state->bv);
+    if (ret == -1) {
+        DEBUG(1, ("ber_flatten failed.\n"));
+        talloc_zfree(req);
+        return NULL;
+    }
+
+    DEBUG(4, ("Executing extended operation\n"));
+
+    ret = ldap_extended_operation(state->sh->ldap, LDAP_EXOP_MODIFY_PASSWD,
+                                  state->bv, NULL, NULL, &state->msgid);
+    if (ret == -1 || state->msgid == -1) {
+        DEBUG(1, ("ldap_extended_operation failed\n"));
+        goto fail;
+    }
+    DEBUG(8, ("ldap_extended_operation sent, msgid = %d\n", state->msgid));
+
+    /* FIXME: get timeouts from configuration, for now 5 secs. */
+    ret = sdap_op_add(state, ev, state->sh, state->msgid,
+                      sdap_exop_modify_passwd_done, req, 5);
+    if (ret) {
+        DEBUG(1, ("Failed to set up operation!\n"));
+        goto fail;
+    }
+
+    return req;
+
+fail:
+    tevent_req_error(req, EIO);
+    tevent_req_post(req, ev);
+    return req;
+}
+
+static void sdap_exop_modify_passwd_done(void *pvt, int error, struct sdap_msg *reply)
+{
+    struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
+    struct sdap_exop_modify_passwd_state *state = tevent_req_data(req,
+                                         struct sdap_exop_modify_passwd_state);
+    char *errmsg;
+    int ret;
+
+    if (error) {
+        tevent_req_error(req, error);
+        return;
+    }
+
+    state->reply = talloc_steal(state, reply);
+
+    ret = ldap_parse_result(state->sh->ldap, state->reply->msg,
+                            &state->result, NULL, &errmsg, NULL, NULL, 0);
+    if (ret != LDAP_SUCCESS) {
+        DEBUG(2, ("ldap_parse_result failed (%d)\n", state->msgid));
+        tevent_req_error(req, EIO);
+        return;
+    }
+
+    DEBUG(3, ("ldap_extended_operation result: %s(%d), %s\n",
+              ldap_err2string(state->result), state->result, errmsg));
+
+    tevent_req_done(req);
+}
+
+int sdap_exop_modify_passwd_recv(struct tevent_req *req,
+                                 enum sdap_result *result)
+{
+    struct sdap_exop_modify_passwd_state *state = tevent_req_data(req,
+                                         struct sdap_exop_modify_passwd_state);
+    enum tevent_req_state tstate;
+    uint64_t err;
+
+    *result = SDAP_ERROR;
+
+    if (tevent_req_is_error(req, &tstate, &err)) {
+        return err;
+    }
+
+    if (state->result == LDAP_SUCCESS) {
+        *result = SDAP_SUCCESS;
+    }
+
+    return EOK;
+}
diff --git a/server/providers/ldap/sdap_async.h b/server/providers/ldap/sdap_async.h
index 6ed9532..4012729 100644
--- a/server/providers/ldap/sdap_async.h
+++ b/server/providers/ldap/sdap_async.h
@@ -85,3 +85,11 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
                                         const char *name,
                                         const char **grp_attrs);
 int sdap_get_initgr_recv(struct tevent_req *req);
+
+struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
+                                                struct tevent_context *ev,
+                                                struct sdap_handle *sh,
+                                                char *user_dn,
+                                                char *password,
+                                                char *new_password);
+int sdap_exop_modify_passwd_recv(struct tevent_req *req, enum sdap_result *result);
-- 
1.6.2.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]