/*
SSSD
Async LDAP Helper routines - retrieving users
Copyright (C) Simo Sorce <ssorce@redhat.com> - 2009
Copyright (C) 2010, Ralf Haferkamp <rhafer@suse.de>, Novell Inc.
Copyright (C) Jan Zeleny <jzeleny@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"
#include "providers/ldap/sdap_idmap.h"
#include "providers/ldap/sdap_users.h"
{
char *c;
if (c == NULL) {
return;
}
while(*(++c) != '\0') {
c[0] = toupper(*c);
}
return;
}
/* ==Save-User-Entry====================================================== */
static errno_t
struct sysdb_attrs *attrs,
char *sid_str,
char *dom_sid_str,
{
char *group_sid_str;
if (!tmpctx) {
goto done;
}
&primary_gid);
goto done;
}
/* The primary group ID is just the RID part of the objectSID
* of the group. Generate the GID by adding this to the domain
* SID value.
*/
/* First, get the domain SID if we didn't do so above */
if (!dom_sid_str) {
&dom_sid_str);
"Could not parse domain SID from [%s]\n", sid_str);
goto done;
}
}
/* Add the RID to the end */
(unsigned long) primary_gid);
if (!group_sid_str) {
goto done;
}
/* Convert the SID into a UNIX group ID */
done:
return ret;
}
/* FIXME: support storing additional attributes */
struct sdap_options *opts,
struct sss_domain_info *dom,
struct sysdb_attrs *attrs,
char **_usn_value,
{
int ret;
const char *pwd;
const char *gecos;
const char *homedir;
const char *shell;
size_t i;
int cache_timeout;
bool use_id_mapping;
char *sid_str;
size_t c;
char *p1;
char *p2;
if (!tmpctx) {
goto done;
}
if (user_attrs == NULL) {
goto done;
}
/* Always store SID string if available */
&sid_str);
sss_strerror(ret));
goto done;
}
} else {
sss_strerror(ret));
}
/* Always store UUID if available */
}
/* If this object has a SID available, we will determine the correct
* domain by its SID. */
if (subdomain) {
} else {
"domain\n", sid_str);
}
}
goto done;
}
goto done;
}
goto done;
}
}
if (!gecos) {
/* Fall back to the user's full name */
}
sid_str);
/* Retrieve or map the UID as appropriate */
if (use_id_mapping) {
"unix ID to user [%s].\n", user_name);
goto done;
}
/* Convert the SID into a UNIX user ID */
goto done;
goto done;
}
/* Store the UID in the ldap_attrs so it doesn't get
* treated as a missing attribute from LDAP and removed.
*/
if (ret) {
goto done;
}
} else {
&uid);
"no uid provided for [%s] in domain [%s].\n",
goto done;
}
}
/* check that the uid is valid for this domain */
"User [%s] filtered out! (uid out of range)\n",
goto done;
}
if (use_id_mapping) {
&gid);
if (ret) {
"Cannot get the GID for [%s] in domain [%s].\n",
goto done;
}
if (IS_SUBDOMAIN(dom)) {
/* For subdomain users, only create the private group as
* the subdomain is an MPG domain.
* But we have to save the GID of the original primary group
* becasuse otherwise this information might be lost because
* typically (Unix and AD) the user is not listed in his primary
* group as a member.
*/
goto done;
}
gid = 0;
}
/* Store the GID in the ldap_attrs so it doesn't get
* treated as a missing attribute from LDAP and removed.
*/
} else {
&gid);
"no gid provided for [%s] in domain [%s].\n",
goto done;
}
}
/* check that the gid is valid for this domain */
if (IS_SUBDOMAIN(dom) == false &&
"User [%s] filtered out! (primary gid out of range)\n",
goto done;
}
if (ret) {
goto done;
}
"originalDN is not available for [%s].\n", user_name);
} else {
if (ret) {
goto done;
}
}
if (ret) {
goto done;
}
if (el->num_values == 0) {
"Original memberOf is not available for [%s].\n", user_name);
} else {
"Adding original memberOf attributes to [%s].\n", user_name);
for (i = 0; i < el->num_values; i++) {
if (ret) {
goto done;
}
}
}
"original mod-Timestamp",
goto done;
}
if (ret) {
goto done;
}
if (el->num_values == 0) {
"Original USN value is not available for [%s].\n", user_name);
} else {
if (ret) {
goto done;
}
if (!usn_value) {
goto done;
}
}
if (ret) {
goto done;
}
if (el->num_values == 0) {
"User principal is not available for [%s].\n", user_name);
} else {
for (c = 0; c < el->num_values; c++) {
if (!upn) {
goto done;
}
/* Check for IPA Kerberos enterprise principal strings
* 'user\@my.realm@IPA.REALM' and use 'user@my.realm' */
*p1 = '\0';
*p2 = '\0';
goto done;
}
}
}
"Adding user principal [%s] to attributes of [%s].\n",
if (ret) {
goto done;
}
}
}
if (ret) {
goto done;
}
}
goto done;
}
/* Make sure that any attributes we requested from LDAP that we
* did not receive are also removed from the sysdb
*/
goto done;
}
if (_usn_value) {
}
done:
if (ret) {
"Failed to save user [%s]\n",
}
return ret;
}
/* ==Generic-Function-to-save-multiple-users============================= */
struct sss_domain_info *dom,
struct sdap_options *opts,
struct sysdb_attrs **users,
int num_users,
char **_usn_value)
{
char *usn_value;
int ret;
int i;
bool in_transaction = false;
if (num_users == 0) {
/* Nothing to do if there are no users */
return EOK;
}
if (!tmpctx) {
return ENOMEM;
}
if (ret) {
goto done;
}
in_transaction = true;
for (i = 0; i < num_users; i++) {
/* Do not fail completely on errors.
* Just report the failure to save and go on */
if (ret) {
} else {
}
if (usn_value) {
if (higher_usn) {
} else {
}
} else {
}
}
}
if (ret) {
goto done;
}
in_transaction = false;
if (_usn_value) {
}
done:
if (in_transaction) {
}
}
return ret;
}
/* ==Search-Users-with-filter============================================= */
struct sdap_search_user_state {
const char **attrs;
const char *base_filter;
const char *filter;
int timeout;
char *higher_usn;
};
struct sysdb_attrs **users,
struct tevent_context *ev,
struct sss_domain_info *dom,
struct sdap_options *opts,
struct sdap_search_base **search_bases,
struct sdap_handle *sh,
const char **attrs,
const char *filter,
int timeout,
{
if (!state->search_bases) {
"User lookup request without a search base\n");
goto done;
}
done:
}
return req;
}
{
bool need_paging = false;
int sizelimit = 0;
return ENOMEM;
}
"Searching for users with base [%s]\n",
switch (state->lookup_type) {
case SDAP_LOOKUP_SINGLE:
break;
/* Only requests that can return multiple entries should require
* the paging control
*/
case SDAP_LOOKUP_WILDCARD:
need_paging = true;
break;
case SDAP_LOOKUP_ENUMERATE:
need_paging = true;
break;
}
return ENOMEM;
}
return EOK;
}
{
struct tevent_req);
struct sdap_search_user_state);
int ret;
bool next_base = false;
if (ret) {
return;
}
"Search for users, returned %zu results.\n", count);
count == 0) {
/* No users found in this search or looking up multiple entries */
next_base = true;
}
/* Add this batch of users to the list */
if (count > 0) {
struct sysdb_attrs *,
return;
}
}
if (next_base) {
/* There are more search bases to try */
}
return;
}
}
/* No more search bases
* Return ENOENT if no users were found
*/
return;
}
}
struct sysdb_attrs **users,
{
bool filter;
/* Always copy all objects for wildcard lookups. */
}
{
struct sdap_search_user_state);
if (higher_usn) {
}
if (users) {
}
if (count) {
}
return EOK;
}
/* ==Search-And-Save-Users-with-filter============================================= */
struct sdap_get_users_state {
const char *filter;
char *higher_usn;
};
struct tevent_context *ev,
struct sss_domain_info *dom,
struct sdap_options *opts,
struct sdap_search_base **search_bases,
struct sdap_handle *sh,
const char **attrs,
const char *filter,
int timeout,
{
goto done;
}
done:
}
return req;
}
{
struct tevent_req);
struct sdap_get_users_state);
int ret;
if (ret) {
}
return;
}
&state->higher_usn);
if (ret) {
return;
}
}
{
struct sdap_get_users_state);
if (usn_value) {
}
return EOK;
}
/* ==Fetch-Fallback-local-user============================================ */
struct sysdb_attrs ***reply)
{
int ret;
if (name) {
} else {
}
if (!pwd) {
}
if (!ua) {
goto done;
}
if (!user) {
goto done;
}
goto done;
}
goto done;
}
}
goto done;
}
goto done;
}
goto done;
}
}
goto done;
}
}
goto done;
}
}
done:
} else {
}
return ret;
}