21 |
21 |
/*
|
22 |
22 |
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
23 |
23 |
* Copyright 2017 Nexenta Systems, Inc. All rights reserved.
|
|
24 |
* Copyright 2020 Joyent, Inc.
|
24 |
25 |
*/
|
25 |
26 |
|
26 |
27 |
#include <stdio.h>
|
... | ... | |
3595 |
3596 |
return (rc);
|
3596 |
3597 |
}
|
3597 |
3598 |
|
|
3599 |
typedef struct lookup_data {
|
|
3600 |
const char *lkd_dn;
|
|
3601 |
const char *lkd_service;
|
|
3602 |
const char *lkd_filter;
|
|
3603 |
const ns_cred_t *lkd_cred;
|
|
3604 |
ns_conn_user_t *lkd_user;
|
|
3605 |
} lookup_data_t;
|
|
3606 |
|
3598 |
3607 |
/*
|
3599 |
|
* find_domainname performs one or more LDAP searches to
|
3600 |
|
* find the value of the nisdomain attribute associated with
|
3601 |
|
* the input DN (with no retry).
|
|
3608 |
* This creates a service search descriptor that can be used to
|
|
3609 |
* retrieve a specific DN by using the DN as the basedn with a search
|
|
3610 |
* scope of 'base'. We don't use any service SSDs in this instance since
|
|
3611 |
* they are intended to search specific locations/subtrees and filter the
|
|
3612 |
* results, while here we are wanting to retrieve a specific entry.
|
3602 |
3613 |
*/
|
3603 |
|
|
3604 |
3614 |
static int
|
3605 |
|
find_domainname(const char *dn, char **domainname, const ns_cred_t *cred,
|
3606 |
|
ns_ldap_error_t **errorp, ns_conn_user_t *conn_user)
|
|
3615 |
lookup_create_ssd(lookup_data_t *dn_data, ns_ldap_search_desc_t **descpp)
|
3607 |
3616 |
{
|
|
3617 |
ns_ldap_search_desc_t *dptr;
|
|
3618 |
|
|
3619 |
*descpp = NULL;
|
3608 |
3620 |
|
|
3621 |
dptr = calloc(1, sizeof (ns_ldap_search_desc_t *));
|
|
3622 |
if (dptr == NULL)
|
|
3623 |
return (NS_LDAP_MEMORY);
|
|
3624 |
|
|
3625 |
dptr->basedn = strdup(dn_data->lkd_dn);
|
|
3626 |
dptr->scope = NS_LDAP_SCOPE_BASE;
|
|
3627 |
dptr->filter = strdup(UIDFILTER);
|
|
3628 |
|
|
3629 |
if (dptr->basedn == NULL || dptr->filter == NULL) {
|
|
3630 |
__ns_ldap_freeASearchDesc(dptr);
|
|
3631 |
return (NS_LDAP_MEMORY);
|
|
3632 |
}
|
|
3633 |
|
|
3634 |
*descpp = dptr;
|
|
3635 |
return (NS_LDAP_SUCCESS);
|
|
3636 |
}
|
|
3637 |
|
|
3638 |
static int
|
|
3639 |
lookup_dn(lookup_data_t *dn_data, const char **attrs,
|
|
3640 |
ns_ldap_result_t **resultp, ns_ldap_error_t **errorp)
|
|
3641 |
{
|
3609 |
3642 |
ns_ldap_cookie_t *cookie;
|
3610 |
|
ns_ldap_search_desc_t **sdlist;
|
3611 |
|
ns_ldap_search_desc_t *dptr;
|
3612 |
|
int rc;
|
3613 |
|
char **value;
|
|
3643 |
int rc = 0;
|
3614 |
3644 |
int flags = 0;
|
3615 |
3645 |
|
3616 |
|
*domainname = NULL;
|
3617 |
3646 |
*errorp = NULL;
|
|
3647 |
*resultp = NULL;
|
|
3648 |
|
|
3649 |
if (dn_data == NULL || dn_data->lkd_dn == NULL ||
|
|
3650 |
dn_data->lkd_dn[0] == '\0' || dn_data->lkd_filter == NULL)
|
|
3651 |
return (NS_LDAP_INVALID_PARAM);
|
3618 |
3652 |
|
3619 |
|
/* Initialize State machine cookie */
|
3620 |
3653 |
cookie = init_search_state_machine();
|
3621 |
|
if (cookie == NULL) {
|
|
3654 |
if (cookie == NULL)
|
3622 |
3655 |
return (NS_LDAP_MEMORY);
|
3623 |
|
}
|
3624 |
|
cookie->conn_user = conn_user;
|
3625 |
3656 |
|
3626 |
|
/* see if need to follow referrals */
|
3627 |
|
rc = __s_api_toFollowReferrals(flags,
|
3628 |
|
&cookie->followRef, errorp);
|
3629 |
|
if (rc != NS_LDAP_SUCCESS) {
|
3630 |
|
delete_search_cookie(cookie);
|
3631 |
|
return (rc);
|
3632 |
|
}
|
|
3657 |
rc = __s_api_toFollowReferrals(flags, &cookie->followRef, errorp);
|
|
3658 |
if (rc != NS_LDAP_SUCCESS)
|
|
3659 |
goto out;
|
3633 |
3660 |
|
3634 |
|
/* Create default service Desc */
|
3635 |
|
sdlist = (ns_ldap_search_desc_t **)calloc(2,
|
3636 |
|
sizeof (ns_ldap_search_desc_t *));
|
3637 |
|
if (sdlist == NULL) {
|
3638 |
|
delete_search_cookie(cookie);
|
3639 |
|
cookie = NULL;
|
3640 |
|
return (NS_LDAP_MEMORY);
|
3641 |
|
}
|
3642 |
|
dptr = (ns_ldap_search_desc_t *)
|
3643 |
|
calloc(1, sizeof (ns_ldap_search_desc_t));
|
3644 |
|
if (dptr == NULL) {
|
3645 |
|
free(sdlist);
|
3646 |
|
delete_search_cookie(cookie);
|
3647 |
|
cookie = NULL;
|
3648 |
|
return (NS_LDAP_MEMORY);
|
|
3661 |
/* 1 for SSD, 1 for terminating NULL */
|
|
3662 |
cookie->sdlist = calloc(2, sizeof (ns_ldap_search_desc_t *));
|
|
3663 |
if (cookie->sdlist == NULL) {
|
|
3664 |
rc = NS_LDAP_MEMORY;
|
|
3665 |
goto out;
|
3649 |
3666 |
}
|
3650 |
|
sdlist[0] = dptr;
|
3651 |
3667 |
|
3652 |
|
/* search base is dn */
|
3653 |
|
dptr->basedn = strdup(dn);
|
3654 |
|
|
3655 |
|
/* search scope is base */
|
3656 |
|
dptr->scope = NS_LDAP_SCOPE_BASE;
|
|
3668 |
rc = lookup_create_ssd(dn_data, &cookie->sdlist[0]);
|
|
3669 |
if (rc != NS_LDAP_SUCCESS)
|
|
3670 |
goto out;
|
3657 |
3671 |
|
3658 |
|
/* search filter is "nisdomain=*" */
|
3659 |
|
dptr->filter = strdup(_NIS_FILTER);
|
|
3672 |
if (dn_data->lkd_service != NULL) {
|
|
3673 |
/*
|
|
3674 |
* If a service was specified, set that on the cookie so
|
|
3675 |
* that search_state_machine() will properly map
|
|
3676 |
* attributes and objectclasses.
|
|
3677 |
*/
|
|
3678 |
cookie->service = strdup(dn_data->lkd_service);
|
|
3679 |
if (cookie->service == NULL) {
|
|
3680 |
rc = NS_LDAP_MEMORY;
|
|
3681 |
goto out;
|
|
3682 |
}
|
|
3683 |
}
|
3660 |
3684 |
|
3661 |
|
cookie->sdlist = sdlist;
|
3662 |
|
cookie->i_filter = strdup(dptr->filter);
|
3663 |
|
cookie->i_attr = nis_domain_attrs;
|
3664 |
|
cookie->i_auth = cred;
|
|
3685 |
cookie->i_attr = attrs;
|
|
3686 |
cookie->i_auth = dn_data->lkd_cred;
|
3665 |
3687 |
cookie->i_flags = 0;
|
|
3688 |
cookie->i_filter = strdup(dn_data->lkd_filter);
|
|
3689 |
if (cookie->i_filter == NULL) {
|
|
3690 |
rc = NS_LDAP_MEMORY;
|
|
3691 |
goto out;
|
|
3692 |
}
|
3666 |
3693 |
|
3667 |
|
/* Process search */
|
3668 |
|
rc = search_state_machine(cookie, INIT, 0);
|
3669 |
|
|
3670 |
|
/* Copy domain name if found */
|
|
3694 |
/*
|
|
3695 |
* Actually perform the search. The return value is only used when
|
|
3696 |
* iterating through multiple results. Since we are searching with
|
|
3697 |
* a scope of base, we will always get at most one result entry,
|
|
3698 |
* we ignore the return value and look at err_rc to determine if
|
|
3699 |
* there were any errors.
|
|
3700 |
*/
|
|
3701 |
(void) search_state_machine(cookie, INIT, 0);
|
3671 |
3702 |
rc = cookie->err_rc;
|
|
3703 |
|
3672 |
3704 |
if (rc != NS_LDAP_SUCCESS) {
|
3673 |
|
if (conn_user != NULL && conn_user->ns_error != NULL) {
|
3674 |
|
*errorp = conn_user->ns_error;
|
3675 |
|
conn_user->ns_error = NULL;
|
|
3705 |
ns_conn_user_t *user = dn_data->lkd_user;
|
|
3706 |
|
|
3707 |
if (user != NULL && user->ns_error != NULL) {
|
|
3708 |
*errorp = user->ns_error;
|
|
3709 |
user->ns_error = NULL;
|
3676 |
3710 |
} else {
|
3677 |
3711 |
*errorp = cookie->errorp;
|
|
3712 |
cookie->errorp = NULL;
|
3678 |
3713 |
}
|
3679 |
|
}
|
3680 |
|
if (cookie->result == NULL)
|
|
3714 |
} else if (cookie->result != NULL) {
|
|
3715 |
*resultp = cookie->result;
|
|
3716 |
cookie->result = NULL;
|
|
3717 |
} else {
|
3681 |
3718 |
rc = NS_LDAP_NOTFOUND;
|
3682 |
|
if (rc == NS_LDAP_SUCCESS) {
|
3683 |
|
value = __ns_ldap_getAttr(cookie->result->entry,
|
3684 |
|
_NIS_DOMAIN);
|
3685 |
|
if (value[0])
|
3686 |
|
*domainname = strdup(value[0]);
|
3687 |
|
else
|
3688 |
|
rc = NS_LDAP_NOTFOUND;
|
3689 |
3719 |
}
|
3690 |
|
if (cookie->result != NULL)
|
3691 |
|
(void) __ns_ldap_freeResult(&cookie->result);
|
3692 |
|
cookie->errorp = NULL;
|
|
3720 |
|
|
3721 |
out:
|
3693 |
3722 |
delete_search_cookie(cookie);
|
3694 |
|
cookie = NULL;
|
|
3723 |
return (rc);
|
|
3724 |
}
|
|
3725 |
|
|
3726 |
/*
|
|
3727 |
* find_domainname performs one or more LDAP searches to
|
|
3728 |
* find the value of the nisdomain attribute associated with
|
|
3729 |
* the input DN (with no retry).
|
|
3730 |
*/
|
|
3731 |
|
|
3732 |
static int
|
|
3733 |
find_domainname(const char *dn, char **domainname, const ns_cred_t *cred,
|
|
3734 |
ns_ldap_error_t **errorp, ns_conn_user_t *conn_user)
|
|
3735 |
{
|
|
3736 |
lookup_data_t ldata;
|
|
3737 |
ns_ldap_result_t *result;
|
|
3738 |
char **value;
|
|
3739 |
int rc;
|
|
3740 |
|
|
3741 |
*domainname = NULL;
|
|
3742 |
*errorp = NULL;
|
|
3743 |
|
|
3744 |
ldata.lkd_dn = dn;
|
|
3745 |
ldata.lkd_service = NULL;
|
|
3746 |
ldata.lkd_filter = _NIS_FILTER;
|
|
3747 |
ldata.lkd_cred = cred;
|
|
3748 |
ldata.lkd_user = conn_user;
|
|
3749 |
|
|
3750 |
rc = lookup_dn(&ldata, nis_domain_attrs, &result, errorp);
|
|
3751 |
if (rc != NS_LDAP_SUCCESS)
|
|
3752 |
return (rc);
|
|
3753 |
|
|
3754 |
value = __ns_ldap_getAttr(result->entry, _NIS_DOMAIN);
|
|
3755 |
|
|
3756 |
if (value[0] != NULL) {
|
|
3757 |
*domainname = strdup(value[0]);
|
|
3758 |
if (*domainname == NULL)
|
|
3759 |
rc = NS_LDAP_MEMORY;
|
|
3760 |
} else {
|
|
3761 |
rc = NS_LDAP_NOTFOUND;
|
|
3762 |
}
|
|
3763 |
|
|
3764 |
(void) __ns_ldap_freeResult(&result);
|
3695 |
3765 |
return (rc);
|
3696 |
3766 |
}
|
3697 |
3767 |
|
... | ... | |
4239 |
4309 |
};
|
4240 |
4310 |
|
4241 |
4311 |
int
|
4242 |
|
__ns_ldap_dn2uid(const char *dn, char **userID, const ns_cred_t *cred,
|
|
4312 |
__ns_ldap_dn2uid(const char *dn, char **userIDp, const ns_cred_t *cred,
|
4243 |
4313 |
ns_ldap_error_t **errorp)
|
4244 |
4314 |
{
|
4245 |
|
ns_ldap_result_t *result = NULL;
|
4246 |
|
char *filter, *userdata;
|
4247 |
|
char errstr[MAXERROR];
|
4248 |
|
char **value;
|
4249 |
|
int rc = 0;
|
4250 |
|
size_t len;
|
|
4315 |
lookup_data_t ldata;
|
|
4316 |
ns_ldap_result_t *result;
|
|
4317 |
char **value;
|
|
4318 |
int rc;
|
4251 |
4319 |
|
4252 |
4320 |
*errorp = NULL;
|
4253 |
|
*userID = NULL;
|
|
4321 |
*userIDp = NULL;
|
4254 |
4322 |
if ((dn == NULL) || (dn[0] == '\0'))
|
4255 |
4323 |
return (NS_LDAP_INVALID_PARAM);
|
4256 |
4324 |
|
4257 |
|
len = strlen(UIDDNFILTER) + strlen(dn) + 1;
|
4258 |
|
filter = malloc(len);
|
4259 |
|
if (filter == NULL) {
|
4260 |
|
return (NS_LDAP_MEMORY);
|
4261 |
|
}
|
4262 |
|
(void) snprintf(filter, len, UIDDNFILTER, dn);
|
4263 |
|
|
4264 |
|
len = strlen(UIDDNFILTER_SSD) + strlen(dn) + 1;
|
4265 |
|
userdata = malloc(len);
|
4266 |
|
if (userdata == NULL) {
|
4267 |
|
free(filter);
|
4268 |
|
return (NS_LDAP_MEMORY);
|
4269 |
|
}
|
4270 |
|
(void) snprintf(userdata, len, UIDDNFILTER_SSD, dn);
|
|
4325 |
/*
|
|
4326 |
* Many LDAP servers do not support using the dn in a search
|
|
4327 |
* filter. As a result, we unfortunately cannot use __ns_ldap_list()
|
|
4328 |
* to lookup the DN. Instead we perform a search with the baseDN
|
|
4329 |
* being the DN we are looking for with a scope of 'base' to
|
|
4330 |
* return the entry, as this should be supported by all LDAP servers.
|
|
4331 |
*/
|
|
4332 |
ldata.lkd_dn = dn;
|
4271 |
4333 |
|
4272 |
4334 |
/*
|
4273 |
|
* Unlike uid2dn, we DO want attribute mapping, so that
|
4274 |
|
* "uid" is mapped to/from samAccountName, for example.
|
|
4335 |
* Since we are looking up a user account by its DN, use the attribute
|
|
4336 |
* and objectclass mappings (if present) for the passwd service.
|
4275 |
4337 |
*/
|
4276 |
|
rc = __ns_ldap_list("passwd", filter,
|
4277 |
|
__s_api_merge_SSD_filter,
|
4278 |
|
dn2uid_attrs, cred, 0,
|
4279 |
|
&result, errorp, NULL,
|
4280 |
|
userdata);
|
4281 |
|
free(filter);
|
4282 |
|
filter = NULL;
|
4283 |
|
free(userdata);
|
4284 |
|
userdata = NULL;
|
4285 |
|
if (rc != NS_LDAP_SUCCESS)
|
4286 |
|
goto out;
|
|
4338 |
ldata.lkd_service = "passwd";
|
|
4339 |
ldata.lkd_filter = UIDDNFILTER;
|
|
4340 |
ldata.lkd_cred = cred;
|
|
4341 |
ldata.lkd_user = NULL;
|
4287 |
4342 |
|
4288 |
|
if (result->entries_count > 1) {
|
4289 |
|
(void) sprintf(errstr,
|
4290 |
|
gettext("Too many entries are returned for %s"), dn);
|
4291 |
|
MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, strdup(errstr),
|
4292 |
|
NS_LDAP_MEMORY);
|
4293 |
|
rc = NS_LDAP_INTERNAL;
|
4294 |
|
goto out;
|
4295 |
|
}
|
|
4343 |
rc = lookup_dn(&ldata, dn2uid_attrs, &result, errorp);
|
|
4344 |
if (rc != NS_LDAP_SUCCESS)
|
|
4345 |
return (rc);
|
4296 |
4346 |
|
4297 |
4347 |
value = __ns_ldap_getAttr(result->entry, _P_UID);
|
4298 |
|
if (value == NULL || value[0] == NULL) {
|
|
4348 |
if (value[0] != NULL) {
|
|
4349 |
*userIDp = strdup(value[0]);
|
|
4350 |
if (*userIDp == NULL)
|
|
4351 |
rc = NS_LDAP_MEMORY;
|
|
4352 |
} else {
|
4299 |
4353 |
rc = NS_LDAP_NOTFOUND;
|
4300 |
|
goto out;
|
4301 |
4354 |
}
|
4302 |
4355 |
|
4303 |
|
*userID = strdup(value[0]);
|
4304 |
|
rc = NS_LDAP_SUCCESS;
|
4305 |
|
|
4306 |
|
out:
|
4307 |
4356 |
(void) __ns_ldap_freeResult(&result);
|
4308 |
|
result = NULL;
|
4309 |
4357 |
return (rc);
|
4310 |
4358 |
}
|
4311 |
4359 |
|