ipa_s2n_exop.c revision ac7a7ee3d1e138818a1ed78758f7dd3c3306a56b
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder IPA Helper routines - external users and groups with s2n plugin
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder Copyright (C) Sumit Bose <sbose@redhat.com> - 2011
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder This program is free software; you can redistribute it and/or modify
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder it under the terms of the GNU General Public License as published by
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder the Free Software Foundation; either version 3 of the License, or
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder (at your option) any later version.
99b26e2ab8ba89bc9a050c1524137eb6269e2753Christian Maeder This program is distributed in the hope that it will be useful,
18548c6cc2dff13bf9f5f08b3f6cde6ca914df1dChristian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
92ae4d5885ea837ffe3dae9b2de742f871229b94Christian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder GNU General Public License for more details.
ef1c24c8229ade3ac872febebd18c181e32fb9c4Christian Maeder You should have received a copy of the GNU General Public License
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder along with this program. If not, see <http://www.gnu.org/licenses/>.
736fe640b202e3fe7288fad8251d5b210c5d8d87Christian Maeder#include "providers/ldap/sdap_async_private.h"
de8eee2014437ec4020be15cd363257f87e79943Christian Maeder/* ==Sid2Name Extended Operation============================================= */
ea5ccb1c6e89486a54e1f4bd95840147e96093edChristian Maeder#define EXOP_SID2NAME_OID "2.16.840.1.113730.3.8.10.4"
473f5af6e4803fbeecc814065952396f2501039bChristian Maederstatic void ipa_s2n_exop_done(struct sdap_op *op,
04c445e50a1d8b95e667595594e6b551c8b2ff59Simon Ulbrichtstatic struct tevent_req *ipa_s2n_exop_send(TALLOC_CTX *mem_ctx,
526e7f36639cb58e3c99a54bea082499a6b04a25Christian Maeder req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_exop_state);
275698320a734a6fd647ea6a461d6ce38862da1dChristian Maeder DEBUG(SSSDBG_TRACE_FUNC, ("Executing extended operation\n"));
6a6689ad6d4c70af2ce3389f39a50982f20fd939Christian Maeder ret = ldap_extended_operation(state->sh->ldap, EXOP_SID2NAME_OID,
df67ddf64192bfcae6ece65255ad796a17cbe532Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, ("ldap_extended_operation failed\n"));
275698320a734a6fd647ea6a461d6ce38862da1dChristian Maeder DEBUG(SSSDBG_TRACE_INTERNAL, ("ldap_extended_operation sent, msgid = %d\n", msgid));
526e7f36639cb58e3c99a54bea082499a6b04a25Christian Maeder /* FIXME: get timeouts from configuration, for now 10 secs. */
275698320a734a6fd647ea6a461d6ce38862da1dChristian Maeder ret = sdap_op_add(state, ev, state->sh, msgid, ipa_s2n_exop_done, req, 10,
275698320a734a6fd647ea6a461d6ce38862da1dChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to set up operation!\n"));
18548c6cc2dff13bf9f5f08b3f6cde6ca914df1dChristian Maederstatic void ipa_s2n_exop_done(struct sdap_op *op,
6a6689ad6d4c70af2ce3389f39a50982f20fd939Christian Maeder struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder struct ipa_s2n_exop_state *state = tevent_req_data(req,
262a0a50e5f72336445bee69630a964660cc8622Christian Maeder ret = ldap_parse_result(state->sh->ldap, reply->msg,
2f0ca8050a33fbc1a23c0bd2dec0d09c17e3c548Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("ldap_parse_result failed (%d)\n", state->op->msgid));
232c13ff6847a6f2bac7163392f80ab692cd7774Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, ("ldap_extended_operation result: %s(%d), %s\n",
232c13ff6847a6f2bac7163392f80ab692cd7774Christian Maeder sss_ldap_err2string(state->result), state->result, errmsg));
232c13ff6847a6f2bac7163392f80ab692cd7774Christian Maeder ret = ldap_parse_extended_result(state->sh->ldap, reply->msg,
eae0d62755147d991cc3e903f74f98ac31a7cd42Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("ldap_parse_extendend_result failed (%d)\n", ret));
99b26e2ab8ba89bc9a050c1524137eb6269e2753Christian Maeder state->retoid = talloc_strdup(state, retoid);
99b26e2ab8ba89bc9a050c1524137eb6269e2753Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht state->retdata = talloc(state, struct berval);
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("talloc failed.\n"));
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht state->retdata->bv_val = talloc_memdup(state->retdata, retdata->bv_val,
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("talloc_memdup failed.\n"));
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbrichtstatic int ipa_s2n_exop_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht struct ipa_s2n_exop_state *state = tevent_req_data(req,
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht *retoid = talloc_steal(mem_ctx, state->retoid);
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht *retdata = talloc_steal(mem_ctx, state->retdata);
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbrichtstatic errno_t talloc_ber_flatten(TALLOC_CTX *mem_ctx, BerElement *ber,
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht tbv->bv_val = talloc_memdup(tbv, bv->bv_val, bv->bv_len);
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht/* The extended operation expect the following ASN.1 encoded request data:
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * ExtdomRequestValue ::= SEQUENCE {
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * inputType ENUMERATED {
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht * posix uid (3),
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht * posix gid (3)
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht * requestType ENUMERATED {
2e76bbbed1c936bb0aee1753837e1c50416847a2Simon Ulbricht * simple (1),
2e76bbbed1c936bb0aee1753837e1c50416847a2Simon Ulbricht * data InputData
2e76bbbed1c936bb0aee1753837e1c50416847a2Simon Ulbricht * InputData ::= CHOICE {
2e76bbbed1c936bb0aee1753837e1c50416847a2Simon Ulbricht * sid OCTET STRING,
2e76bbbed1c936bb0aee1753837e1c50416847a2Simon Ulbricht * name NameDomainData
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * uid PosixUid,
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * gid PosixGid
f6a562e28240e4f9107c199ba7a8e500ccfbfa55Simon Ulbricht * NameDomainData ::= SEQUENCE {
2e76bbbed1c936bb0aee1753837e1c50416847a2Simon Ulbricht * domain_name OCTET STRING,
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * object_name OCTET STRING
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * PosixUid ::= SEQUENCE {
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * domain_name OCTET STRING,
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * uid INTEGER
f6a562e28240e4f9107c199ba7a8e500ccfbfa55Simon Ulbricht * PosixGid ::= SEQUENCE {
f6a562e28240e4f9107c199ba7a8e500ccfbfa55Simon Ulbricht * domain_name OCTET STRING,
f6a562e28240e4f9107c199ba7a8e500ccfbfa55Simon Ulbricht * gid INTEGER
2e2559f894aaa661b199e4fa00609f522bc5482aSimon Ulbrichtstatic errno_t s2n_encode_request(TALLOC_CTX *mem_ctx,
05c714be15ce094d83f1b989cdf5236be78419bfSimon Ulbricht ret = ber_printf(ber, "{ee{ss}}", INP_NAME, REQ_FULL,
05c714be15ce094d83f1b989cdf5236be78419bfSimon Ulbricht ret = ber_printf(ber, "{ee{si}}", INP_POSIX_UID, REQ_FULL,
f6a562e28240e4f9107c199ba7a8e500ccfbfa55Simon Ulbricht ret = ber_printf(ber, "{ee{ss}}", INP_NAME, REQ_FULL,
f6a562e28240e4f9107c199ba7a8e500ccfbfa55Simon Ulbricht ret = ber_printf(ber, "{ee{si}}", INP_POSIX_GID, REQ_FULL,
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht/* If the extendend operation is successful it returns the following ASN.1
9a5e6e537c43a631facd9d87ce1a6c76f4b0af6dSimon Ulbricht * encoded response:
05c714be15ce094d83f1b989cdf5236be78419bfSimon Ulbricht * ExtdomResponseValue ::= SEQUENCE {
1ab66a7e4234c760be9689b05ab4c34ce99dba23Simon Ulbricht * responseType ENUMERATED {
526e7f36639cb58e3c99a54bea082499a6b04a25Christian Maeder * posix_user (3),
526e7f36639cb58e3c99a54bea082499a6b04a25Christian Maeder * posix_group (4)
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * data OutputData
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * OutputData ::= CHOICE {
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * sid OCTET STRING,
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * name NameDomainData,
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * user PosixUser,
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * group PosixGroup
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * NameDomainData ::= SEQUENCE {
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * domain_name OCTET STRING,
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * object_name OCTET STRING
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * PosixUser ::= SEQUENCE {
0bbc28585c7d42913167ff78a862ef25ea59e85eChristian Maeder * domain_name OCTET STRING,
4ed68712ee368cbebfeaa327968583cb022e3c72Christian Maeder * user_name OCTET STRING,
4ed68712ee368cbebfeaa327968583cb022e3c72Christian Maeder * uid INTEGER
4ed68712ee368cbebfeaa327968583cb022e3c72Christian Maeder * gid INTEGER
4ed68712ee368cbebfeaa327968583cb022e3c72Christian Maeder * PosixGroup ::= SEQUENCE {
4ed68712ee368cbebfeaa327968583cb022e3c72Christian Maeder * domain_name OCTET STRING,
993e01fc242fa58d3dcf1b3272cd411726817eeeSimon Ulbricht * group_name OCTET STRING,
4ed68712ee368cbebfeaa327968583cb022e3c72Christian Maeder * gid INTEGER
f3fb0e085030be5bc309d946a6a9c20736dd3e0fSimon Ulbricht * Since we always request the full data set (REQ_FULL), i.e user/group name,
f3fb0e085030be5bc309d946a6a9c20736dd3e0fSimon Ulbricht * domain name and corresponding unix id, only PosixUser (RESP_USER) and
f3fb0e085030be5bc309d946a6a9c20736dd3e0fSimon Ulbricht * PosixGroup (RESP_GROUP) are handled by s2n_response_to_attrs().
eae0d62755147d991cc3e903f74f98ac31a7cd42Christian Maederstatic errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
5896f38ba2934056542cb7cb3e6359e88a622547Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Missing OID or data.\n"));
ea5ccb1c6e89486a54e1f4bd95840147e96093edChristian Maeder if (strcmp(retoid, EXOP_SID2NAME_OID) != 0) {
bd90cf050d470eb42f6e0b79327cc53bd0f80dc9Christian Maeder ("Result has wrong OID, expected [%s], got [%s].\n",
de8eee2014437ec4020be15cd363257f87e79943Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("ber_init failed.\n"));
5a448e9be8c4482a978b174b744237757335140fChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("ber_scanf failed.\n"));
3e87e1dc85fa76cc6eaeb8eafbc0bea77af939f4Christian Maeder attrs = talloc_zero(mem_ctx, struct resp_attrs);
3e87e1dc85fa76cc6eaeb8eafbc0bea77af939f4Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n"));
3f08b178a44369b618a5e0b5f1fc2207fe043aabChristian Maeder tag = ber_scanf(ber, "{aaii}}", &domain_name, &name, &uid, &gid);
3e87e1dc85fa76cc6eaeb8eafbc0bea77af939f4Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("ber_scanf failed.\n"));
3f08b178a44369b618a5e0b5f1fc2207fe043aabChristian Maeder /* Winbind is not consistent with the case of the returned user
ea5ccb1c6e89486a54e1f4bd95840147e96093edChristian Maeder * name. In general all names should be lower case but there are
18548c6cc2dff13bf9f5f08b3f6cde6ca914df1dChristian Maeder * bug in some version of winbind which might lead to upper case
4ed68712ee368cbebfeaa327968583cb022e3c72Christian Maeder * letters in the name. To be on the safe side we explicitly
18548c6cc2dff13bf9f5f08b3f6cde6ca914df1dChristian Maeder * lowercase the name. */
18548c6cc2dff13bf9f5f08b3f6cde6ca914df1dChristian Maeder attrs->a.user.pw_name = sss_tc_utf8_str_tolower(attrs, name);
ef1c24c8229ade3ac872febebd18c181e32fb9c4Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
fd94a6f66ccb5cef99aa42069b61e4b8734dbd3fChristian Maeder tag = ber_scanf(ber, "{aai}}", &domain_name, &name, &gid);
18548c6cc2dff13bf9f5f08b3f6cde6ca914df1dChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("ber_scanf failed.\n"));
df67ddf64192bfcae6ece65255ad796a17cbe532Christian Maeder attrs->a.group.gr_name = talloc_strdup(attrs, name);
4d54e7814b18ce142359c92a5868e6dcff9219b5Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
f675b8f0a612e37472640da57b48d795bef4427eChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Unexpected response type [%d].\n",
f675b8f0a612e37472640da57b48d795bef4427eChristian Maeder attrs->domain_name = talloc_strdup(attrs, domain_name);
f675b8f0a612e37472640da57b48d795bef4427eChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
f675b8f0a612e37472640da57b48d795bef4427eChristian Maederstatic void ipa_s2n_get_user_done(struct tevent_req *subreq);
f675b8f0a612e37472640da57b48d795bef4427eChristian Maederstruct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
5bedf8c26d27eac08962c78379bcb2e5cb529036Christian Maeder if ((name == NULL && id == 0) || (name != NULL && id != 0)) {
5bedf8c26d27eac08962c78379bcb2e5cb529036Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Either a user name or a uid expected, "
5bedf8c26d27eac08962c78379bcb2e5cb529036Christian Maeder "not both or nothing.\n"));
cc9f19b1fe81424205736fe0ae73620395b1bb74Simon Ulbricht req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_get_user_state);
d864f0a0e04e61b5f87963496765eafcf646ed7bChristian Maeder ret = s2n_encode_request(state, dom->name, entry_type, name, id, &bv_req);
a07a6a1143844a6f061a49aefc550e3bdd28f331Christian Maeder subreq = ipa_s2n_exop_send(state, state->ev, state->sh, bv_req);
ea5ccb1c6e89486a54e1f4bd95840147e96093edChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("ipa_s2n_exop_send failed.\n"));
04c445e50a1d8b95e667595594e6b551c8b2ff59Simon Ulbricht tevent_req_set_callback(subreq, ipa_s2n_get_user_done, req);
7c661ba558707feaa5d8a299365c2191e1afabb2Christian Maederstatic void ipa_s2n_get_user_done(struct tevent_req *subreq)
7c661ba558707feaa5d8a299365c2191e1afabb2Christian Maeder struct tevent_req *req = tevent_req_callback_data(subreq,
5bedf8c26d27eac08962c78379bcb2e5cb529036Christian Maeder struct ipa_s2n_get_user_state *state = tevent_req_data(req,
5896f38ba2934056542cb7cb3e6359e88a622547Christian Maeder uint64_t timeout = 10*60*60; /* FIXME: find a better timeout ! */
5727dbcb926ede2e7b05f43685476ce656ce01e4Christian Maeder ret = ipa_s2n_exop_recv(subreq, state, &result, &retoid, &retdata);
5727dbcb926ede2e7b05f43685476ce656ce01e4Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("s2n exop request failed.\n"));
5727dbcb926ede2e7b05f43685476ce656ce01e4Christian Maeder ret = s2n_response_to_attrs(state, retoid, retdata, &attrs);
43d8d7472d3a0a78d9a2c85122815a81deb8689aChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("s2n_response_to_attrs failed.\n"));
5727dbcb926ede2e7b05f43685476ce656ce01e4Christian Maeder if (!(strcasecmp(state->dom->name, attrs->domain_name) == 0 ||
92ae4d5885ea837ffe3dae9b2de742f871229b94Christian Maeder strcasecmp(state->dom->flat_name, attrs->domain_name) == 0))) {
486db0a875bcdd0b80cf0d447d14c9c00a92ae94Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("Unexpected domain name returned, "
486db0a875bcdd0b80cf0d447d14c9c00a92ae94Simon Ulbricht "expected [%s] or [%s], got [%s].\n",
5727dbcb926ede2e7b05f43685476ce656ce01e4Christian Maeder state->dom->flat_name == NULL ? "" : state->dom->flat_name,
2e76bbbed1c936bb0aee1753837e1c50416847a2Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_new_attrs failed.\n"));
2e2559f894aaa661b199e4fa00609f522bc5482aSimon Ulbricht ret = sysdb_attrs_add_string(user_attrs, SYSDB_NAME_ALIAS,
7cb31cb2104c666b2762976f7ed86da10575a980Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_add_string failed.\n"));
7cb31cb2104c666b2762976f7ed86da10575a980Simon Ulbricht ret = sysdb_store_domuser(state->dom, attrs->a.user.pw_name, NULL,
de04c8b0fb11f38a905bdb08a6156f5aa6dc3169Simon Ulbricht ret = sysdb_store_domgroup(state->dom, attrs->a.group.gr_name,
37c793236d73cd400bb268672e0d0f7f97a89a70Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("Unexpected response type [%d].\n",