ipa_s2n_exop.c revision 4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2d
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose/*
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose SSSD
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose IPA Helper routines - external users and groups with s2n plugin
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose Copyright (C) Sumit Bose <sbose@redhat.com> - 2011
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose This program is free software; you can redistribute it and/or modify
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose it under the terms of the GNU General Public License as published by
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose the Free Software Foundation; either version 3 of the License, or
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose (at your option) any later version.
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose This program is distributed in the hope that it will be useful,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose GNU General Public License for more details.
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose You should have received a copy of the GNU General Public License
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose*/
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose#include "util/util.h"
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose#include "util/sss_nss.h"
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose#include "db/sysdb.h"
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose#include "providers/ldap/sdap_async_private.h"
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose#include "providers/ldap/ldap_common.h"
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Boseenum input_types {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose INP_SID = 1,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose INP_NAME,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose INP_POSIX_UID,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose INP_POSIX_GID
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose};
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Boseenum request_types {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose REQ_SIMPLE = 1,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose REQ_FULL
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose};
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Boseenum response_types {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose RESP_SID = 1,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose RESP_NAME,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose RESP_USER,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose RESP_GROUP
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose};
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose/* ==Sid2Name Extended Operation============================================= */
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose#define EXOP_SID2NAME_OID "2.16.840.1.113730.3.8.10.4"
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestruct ipa_s2n_exop_state {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_handle *sh;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_op *op;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int result;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *retoid;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *retdata;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose};
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic void ipa_s2n_exop_done(struct sdap_op *op,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_msg *reply,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int error, void *pvt);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic struct tevent_req *ipa_s2n_exop_send(TALLOC_CTX *mem_ctx,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_context *ev,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_handle *sh,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *bv)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_req *req = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_exop_state *state;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int msgid;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_exop_state);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (!req) return NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->sh = sh;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->result = LDAP_OPERATIONS_ERROR;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->retoid = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->retdata = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_TRACE_FUNC, ("Executing extended operation\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ldap_extended_operation(state->sh->ldap, EXOP_SID2NAME_OID,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose bv, NULL, NULL, &msgid);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == -1 || msgid == -1) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_CRIT_FAILURE, ("ldap_extended_operation failed\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto fail;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_TRACE_INTERNAL, ("ldap_extended_operation sent, msgid = %d\n", msgid));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose /* FIXME: get timeouts from configuration, for now 10 secs. */
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = sdap_op_add(state, ev, state->sh, msgid, ipa_s2n_exop_done, req, 10,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose &state->op);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to set up operation!\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto fail;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return req;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosefail:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_error(req, EIO);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_post(req, ev);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return req;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic void ipa_s2n_exop_done(struct sdap_op *op,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_msg *reply,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int error, void *pvt)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_exop_state *state = tevent_req_data(req,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_exop_state);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *errmsg = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *retoid = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *retdata = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (error) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_error(req, error);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ldap_parse_result(state->sh->ldap, reply->msg,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose &state->result, &errmsg, NULL, NULL,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose NULL, 0);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret != LDAP_SUCCESS) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("ldap_parse_result failed (%d)\n", state->op->msgid));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EIO;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_TRACE_FUNC, ("ldap_extended_operation result: %s(%d), %s\n",
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose sss_ldap_err2string(state->result), state->result, errmsg));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (state->result != LDAP_SUCCESS) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EIO;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ldap_parse_extended_result(state->sh->ldap, reply->msg,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose &retoid, &retdata, 0);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret != LDAP_SUCCESS) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("ldap_parse_extendend_result failed (%d)\n", ret));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EIO;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->retoid = talloc_strdup(state, retoid);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (state->retoid == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->retdata = talloc(state, struct berval);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (state->retdata == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->retdata->bv_len = retdata->bv_len;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->retdata->bv_val = talloc_memdup(state->retdata, retdata->bv_val,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose retdata->bv_len);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (state->retdata->bv_val == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_memdup failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EOK;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosedone:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ldap_memfree(errmsg);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ldap_memfree(retoid);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber_bvfree(retdata);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == EOK) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_done(req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } else {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_error(req, ret);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic int ipa_s2n_exop_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose enum sdap_result *result, char **retoid,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval **retdata)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_exop_state *state = tevent_req_data(req,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_exop_state);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose TEVENT_REQ_RETURN_ON_ERROR(req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (state->result == LDAP_SUCCESS) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *result = SDAP_SUCCESS;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *retoid = talloc_steal(mem_ctx, state->retoid);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *retdata = talloc_steal(mem_ctx, state->retdata);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } else {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *result = SDAP_ERROR;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return EOK;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic errno_t talloc_ber_flatten(TALLOC_CTX *mem_ctx, BerElement *ber,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval **_bv)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *bv = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *tbv = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ber_flatten(ber, &bv);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == -1) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EFAULT;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tbv = talloc_zero(mem_ctx, struct berval);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (tbv == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tbv->bv_len = bv->bv_len;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tbv->bv_val = talloc_memdup(tbv, bv->bv_val, bv->bv_len);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (tbv->bv_val == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EOK;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosedone:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber_bvfree(bv);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == EOK) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *_bv = tbv;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } else {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose talloc_free(tbv);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose/* The extended operation expect the following ASN.1 encoded request data:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * ExtdomRequestValue ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * inputType ENUMERATED {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * sid (1),
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * name (2),
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * posix uid (3),
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * posix gid (3)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * },
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * requestType ENUMERATED {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * simple (1),
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * full (2)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * },
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * data InputData
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * InputData ::= CHOICE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * sid OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * name NameDomainData
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * uid PosixUid,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * gid PosixGid
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * NameDomainData ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * domain_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * object_name OCTET STRING
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * PosixUid ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * domain_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * uid INTEGER
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * PosixGid ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * domain_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * gid INTEGER
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose */
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic errno_t s2n_encode_request(TALLOC_CTX *mem_ctx,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose const char *domain_name,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int entry_type,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose const char *name,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose uint32_t id,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval **_bv)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose BerElement *ber = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber = ber_alloc_t( LBER_USE_DER );
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ber == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose switch (entry_type) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose case BE_REQ_USER:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (name != NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ber_printf(ber, "{ee{ss}}", INP_NAME, REQ_FULL,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose domain_name, name);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } else {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ber_printf(ber, "{ee{si}}", INP_POSIX_UID, REQ_FULL,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose domain_name, id);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose break;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose case BE_REQ_GROUP:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (name != NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ber_printf(ber, "{ee{ss}}", INP_NAME, REQ_FULL,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose domain_name, name);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } else {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ber_printf(ber, "{ee{si}}", INP_POSIX_GID, REQ_FULL,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose domain_name, id);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose break;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose default:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == -1) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EFAULT;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = talloc_ber_flatten(mem_ctx, ber, _bv);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == -1) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EFAULT;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EOK;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosedone:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber_free(ber, 1);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose/* If the extendend operation is successful it returns the following ASN.1
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * encoded response:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * ExtdomResponseValue ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * responseType ENUMERATED {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * sid (1),
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * name (2),
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * posix_user (3),
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * posix_group (4)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * },
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * data OutputData
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * OutputData ::= CHOICE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * sid OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * name NameDomainData,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * user PosixUser,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * group PosixGroup
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * NameDomainData ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * domain_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * object_name OCTET STRING
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * PosixUser ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * domain_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * user_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * uid INTEGER
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * gid INTEGER
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * PosixGroup ::= SEQUENCE {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * domain_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * group_name OCTET STRING,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * gid INTEGER
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * Since we always request the full data set (REQ_FULL), i.e user/group name,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * domain name and corresponding unix id, only PosixUser (RESP_USER) and
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose * PosixGroup (RESP_GROUP) are handled by s2n_response_to_attrs().
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose */
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestruct resp_attrs {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose enum response_types response_type;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *domain_name;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose union {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct passwd user;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct group group;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } a;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose};
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *retoid,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *retdata,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct resp_attrs **resp_attrs)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose BerElement *ber = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber_tag_t tag;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose enum response_types type;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *domain_name = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *name = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose uid_t uid;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose gid_t gid;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct resp_attrs *attrs = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (retoid == NULL || retdata == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("Missing OID or data.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (strcmp(retoid, EXOP_SID2NAME_OID) != 0) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ("Result has wrong OID, expected [%s], got [%s].\n",
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose EXOP_SID2NAME_OID, retoid));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber = ber_init(retdata);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ber == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("ber_init failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tag = ber_scanf(ber, "{e", &type);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (tag == LBER_ERROR) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("ber_scanf failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs = talloc_zero(mem_ctx, struct resp_attrs);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (attrs == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose switch (type) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose case RESP_USER:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tag = ber_scanf(ber, "{aaii}}", &domain_name, &name, &uid, &gid);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (tag == LBER_ERROR) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("ber_scanf failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->a.user.pw_name = talloc_strdup(attrs, name);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (attrs->a.user.pw_name == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->a.user.pw_uid = uid;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->a.user.pw_gid = gid;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose break;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose case RESP_GROUP:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tag = ber_scanf(ber, "{aai}}", &domain_name, &name, &gid);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (tag == LBER_ERROR) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("ber_scanf failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->a.group.gr_name = talloc_strdup(attrs, name);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (attrs->a.group.gr_name == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->a.group.gr_gid = gid;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose break;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose default:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("Unexpected response type [%d].\n",
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose type));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->response_type = type;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->domain_name = talloc_strdup(attrs, domain_name);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (attrs->domain_name == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EOK;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosedone:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber_memfree(domain_name);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber_memfree(name);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ber_free(ber, 1);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == EOK) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose *resp_attrs = attrs;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } else {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose talloc_free(attrs);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestruct ipa_s2n_get_user_state {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_context *ev;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_options *opts;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sss_domain_info *dom;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_handle *sh;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose const char **expected_attrs;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose};
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic void ipa_s2n_get_user_done(struct tevent_req *subreq);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestruct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_context *ev,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_options *opts,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sss_domain_info *dom,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct sdap_handle *sh,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose const char **attrs,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int entry_type,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose const char *name,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose uint32_t id)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_get_user_state *state;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_req *req;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_req *subreq;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *bv_req = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int ret = EFAULT;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if ((name == NULL && id == 0) || (name != NULL && id != 0)) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("Either a user name or a uid expected, "
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose "not both or nothing.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_get_user_state);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (req == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->ev = ev;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->opts = opts;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->dom = dom;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->sh = sh;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose state->expected_attrs = attrs;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = s2n_encode_request(state, dom->name, entry_type, name, id, &bv_req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret != EOK) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto fail;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose subreq = ipa_s2n_exop_send(state, state->ev, state->sh, bv_req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (subreq == NULL) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("ipa_s2n_exop_send failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ENOMEM;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto fail;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_set_callback(subreq, ipa_s2n_get_user_done, req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return req;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosefail:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_error(req, ret);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_post(req, ev);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return req;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosestatic void ipa_s2n_get_user_done(struct tevent_req *subreq)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_req *req = tevent_req_callback_data(subreq,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct tevent_req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_get_user_state *state = tevent_req_data(req,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct ipa_s2n_get_user_state);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose int ret;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose enum sdap_result result;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose char *retoid = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct berval *retdata = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose struct resp_attrs *attrs;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose time_t now;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose uint64_t timeout = 10*60*60; /* FIXME: find a better timeout ! */
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose const char *homedir = NULL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = ipa_s2n_exop_recv(subreq, state, &result, &retoid, &retdata);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose talloc_zfree(subreq);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret != EOK) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("s2n exop request failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = s2n_response_to_attrs(state, retoid, retdata, &attrs);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret != EOK) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("s2n_response_to_attrs failed.\n"));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
70eaade10feedd7845e39170d0b7eebf3a030af1Sumit Bose if (!(strcasecmp(state->dom->name, attrs->domain_name) == 0 ||
70eaade10feedd7845e39170d0b7eebf3a030af1Sumit Bose (state->dom->flat_name != NULL &&
70eaade10feedd7845e39170d0b7eebf3a030af1Sumit Bose strcasecmp(state->dom->flat_name, attrs->domain_name) == 0))) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("Unexpected domain name returned, "
70eaade10feedd7845e39170d0b7eebf3a030af1Sumit Bose "expected [%s] or [%s], got [%s].\n",
70eaade10feedd7845e39170d0b7eebf3a030af1Sumit Bose state->dom->name,
70eaade10feedd7845e39170d0b7eebf3a030af1Sumit Bose state->dom->flat_name == NULL ? "" : state->dom->flat_name,
70eaade10feedd7845e39170d0b7eebf3a030af1Sumit Bose attrs->domain_name));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose now = time(NULL);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose switch (attrs->response_type) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose case RESP_USER:
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose if (state->dom->subdomain_homedir) {
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose homedir = expand_homedir_template(state,
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose state->dom->subdomain_homedir,
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose attrs->a.user.pw_name,
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose attrs->a.user.pw_uid,
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose state->dom->name);
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose if (homedir == NULL) {
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose ret = ENOMEM;
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose goto done;
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose }
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose }
4cf3bc3b94ccf1e60d29c0eb765f02cb49fbac2dSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = sysdb_store_domuser(state->dom, attrs->a.user.pw_name, NULL,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->a.user.pw_uid,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose 0, NULL, /* gecos */
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose homedir, NULL,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose NULL, NULL, timeout, now);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose break;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose case RESP_GROUP:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = sysdb_store_domgroup(state->dom, attrs->a.group.gr_name,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->a.group.gr_gid, NULL, timeout,
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose now);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose break;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose default:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose DEBUG(SSSDBG_OP_FAILURE, ("Unexpected response type [%d].\n",
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose attrs->response_type));
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose ret = EINVAL;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose goto done;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bosedone:
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose if (ret == EOK) {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_done(req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose } else {
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose tevent_req_error(req, ret);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose }
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Boseint ipa_s2n_get_acct_info_recv(struct tevent_req *req)
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose{
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose TEVENT_REQ_RETURN_ON_ERROR(req);
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose return EOK;
36a12aea020a935ffa40505fa02860c3d921ad0cSumit Bose}