ipa_s2n_exop.c revision 9f37bb2012faa136ef7c1f9fe93689ce2be85637
/*
SSSD
IPA Helper routines - external users and groups with s2n plugin
Copyright (C) Sumit Bose <sbose@redhat.com> - 2011
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/ldap_common.h"
enum input_types {
INP_SID = 1,
};
enum request_types {
REQ_SIMPLE = 1,
};
enum response_types {
RESP_SID = 1,
};
/* ==Sid2Name Extended Operation============================================= */
#define EXOP_SID2NAME_OID "2.16.840.1.113730.3.8.10.4"
struct ipa_s2n_exop_state {
struct sdap_handle *sh;
int result;
char *retoid;
};
struct tevent_context *ev,
struct sdap_handle *sh,
{
struct ipa_s2n_exop_state *state;
int ret;
int msgid;
goto fail;
}
/* FIXME: get timeouts from configuration, for now 10 secs. */
if (ret) {
goto fail;
}
return req;
fail:
return req;
}
{
struct ipa_s2n_exop_state);
int ret;
if (error) {
return;
}
NULL, 0);
if (ret != LDAP_SUCCESS) {
goto done;
}
goto done;
}
if (ret != LDAP_SUCCESS) {
goto done;
}
goto done;
}
goto done;
}
goto done;
}
done:
} else {
}
}
{
struct ipa_s2n_exop_state);
*result = SDAP_SUCCESS;
} else {
*result = SDAP_ERROR;
}
return EOK;
}
{
int ret;
if (ret == -1) {
goto done;
}
goto done;
}
goto done;
}
done:
ber_bvfree(bv);
} else {
}
return ret;
}
/* The extended operation expect the following ASN.1 encoded request data:
*
* ExtdomRequestValue ::= SEQUENCE {
* inputType ENUMERATED {
* sid (1),
* name (2),
* posix uid (3),
* posix gid (3)
* },
* requestType ENUMERATED {
* simple (1),
* full (2)
* },
* data InputData
* }
*
* InputData ::= CHOICE {
* sid OCTET STRING,
* name NameDomainData
* uid PosixUid,
* gid PosixGid
* }
*
* NameDomainData ::= SEQUENCE {
* domain_name OCTET STRING,
* object_name OCTET STRING
* }
*
* PosixUid ::= SEQUENCE {
* domain_name OCTET STRING,
* uid INTEGER
* }
*
* PosixGid ::= SEQUENCE {
* domain_name OCTET STRING,
* gid INTEGER
* }
*
*/
const char *domain_name,
int entry_type,
const char *name,
{
int ret;
return ENOMEM;
}
switch (entry_type) {
case BE_REQ_USER:
domain_name, name);
} else {
domain_name, id);
}
break;
case BE_REQ_GROUP:
domain_name, name);
} else {
domain_name, id);
}
break;
default:
goto done;
}
if (ret == -1) {
goto done;
}
if (ret == -1) {
goto done;
}
done:
return ret;
}
/* If the extendend operation is successful it returns the following ASN.1
* encoded response:
*
* ExtdomResponseValue ::= SEQUENCE {
* responseType ENUMERATED {
* sid (1),
* name (2),
* posix_user (3),
* posix_group (4)
* },
* data OutputData
* }
*
* OutputData ::= CHOICE {
* sid OCTET STRING,
* name NameDomainData,
* user PosixUser,
* group PosixGroup
* }
*
* NameDomainData ::= SEQUENCE {
* domain_name OCTET STRING,
* object_name OCTET STRING
* }
*
* PosixUser ::= SEQUENCE {
* domain_name OCTET STRING,
* user_name OCTET STRING,
* uid INTEGER
* gid INTEGER
* }
*
* PosixGroup ::= SEQUENCE {
* domain_name OCTET STRING,
* group_name OCTET STRING,
* gid INTEGER
* }
*
* domain name and corresponding unix id, only PosixUser (RESP_USER) and
* PosixGroup (RESP_GROUP) are handled by s2n_response_to_attrs().
*/
struct resp_attrs {
enum response_types response_type;
char *domain_name;
union {
} a;
};
char *retoid,
struct resp_attrs **resp_attrs)
{
int ret;
enum response_types type;
char *domain_name = NULL;
return EINVAL;
}
("Result has wrong OID, expected [%s], got [%s].\n",
return EINVAL;
}
return EINVAL;
}
if (tag == LBER_ERROR) {
goto done;
}
goto done;
}
switch (type) {
case RESP_USER:
if (tag == LBER_ERROR) {
goto done;
}
/* Winbind is not consistent with the case of the returned user
* name. In general all names should be lower case but there are
* bug in some version of winbind which might lead to upper case
* letters in the name. To be on the safe side we explicitly
* lowercase the name. */
goto done;
}
break;
case RESP_GROUP:
if (tag == LBER_ERROR) {
goto done;
}
goto done;
}
break;
default:
type));
goto done;
}
goto done;
}
done:
*resp_attrs = attrs;
} else {
}
return ret;
}
struct ipa_s2n_get_user_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sss_domain_info *dom;
struct sdap_handle *sh;
const char **expected_attrs;
};
struct tevent_context *ev,
struct sdap_options *opts,
struct sss_domain_info *dom,
struct sdap_handle *sh,
const char **attrs,
int entry_type,
const char *name,
{
struct ipa_s2n_get_user_state *state;
struct tevent_req *req;
struct tevent_req *subreq;
"not both or nothing.\n"));
return NULL;
}
return NULL;
}
goto fail;
}
goto fail;
}
return req;
fail:
return req;
}
{
struct tevent_req);
struct ipa_s2n_get_user_state);
int ret;
enum sdap_result result;
char *name;
char *realm;
char *upn;
goto done;
}
goto done;
}
"expected [%s] or [%s], got [%s].\n",
attrs->domain_name));
goto done;
}
switch (attrs->response_type) {
case RESP_USER:
NULL,
goto done;
}
}
if (user_attrs == NULL) {
goto done;
}
/* we always use the fully qualified name for subdomain users */
if (!name) {
goto done;
}
goto done;
}
/* We also have to store a fake UPN here, because otherwise the
* krb5 child later won't be able to properly construct one as
* the username is fully qualified but the child doesn't have
* access to the regex to deconstruct it */
/* FIXME: The real UPN is available from the PAC, we should get
* it from there. */
if (!realm) {
goto done;
}
if (!upn) {
goto done;
}
goto done;
}
break;
case RESP_GROUP:
/* we always use the fully qualified name for subdomain users */
if (!name) {
goto done;
}
break;
default:
attrs->response_type));
goto done;
}
done:
} else {
}
return;
}
{
return EOK;
}