sysdb_ops.c revision b9941359b3181c42f415530d5ccad0f4664d85fa
/*
SSSD
System Database
Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
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 "db/sysdb_private.h"
#include "db/sysdb_services.h"
#include "db/sysdb_autofs.h"
#include "util/crypto/sss_crypto.h"
#include <time.h>
{
long long int l;
if (!v || !v->data) {
return 0;
}
errno = 0;
if (errno) {
return (uint32_t)-1;
}
if (l < 0 || l > ((uint32_t)(-1))) {
return (uint32_t)-1;
}
return l;
}
/*
* The wrapper around ldb_modify that uses LDB_CONTROL_PERMISSIVE_MODIFY_OID
* so that on adds entries that already exist are skipped and similarly
* entries that are missing are ignored on deletes
*
* Please note this function returns LDB error codes, not sysdb error
* codes on purpose, see usage in callers!
*/
struct ldb_message *msg)
{
struct ldb_request *req;
msg,
NULL,
NULL,
NULL);
false, NULL);
if (ret != LDB_SUCCESS) {
return ret;
}
if (ret == LDB_SUCCESS) {
}
/* Please note this function returns LDB error codes, not sysdb error
* codes on purpose, see usage in callers!
*/
return ret;
}
#define ERROR_OUT(v, r, l) do { v = r; goto l; } while(0)
/* =Remove-Entry-From-Sysdb=============================================== */
bool ignore_not_found)
{
int ret;
switch (ret) {
case LDB_SUCCESS:
return EOK;
case LDB_ERR_NO_SUCH_OBJECT:
if (ignore_not_found) {
return EOK;
}
/* fall through */
default:
return sysdb_error_to_errno(ret);
}
}
{
return EOK;
}
}
bool ignore_not_found)
{
"sysdb_delete_ts_entry failed: %d\n", ret);
} else {
"sysdb_delete_cache_entry failed: %d\n", ret);
}
return ret;
}
/* =Remove-Subentries-From-Sysdb=========================================== */
bool ignore_not_found)
{
struct ldb_message **msgs;
int ret;
int i;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
goto done;
}
LDB_SCOPE_SUBTREE, "(distinguishedName=*)",
if (ret) {
}
if (ret) {
}
goto done;
}
sizeof(struct ldb_message *), compare_ldb_dn_comp_num);
for (i = 0; i < msgs_count; i++) {
if (ret) {
goto done;
}
}
done:
} else {
}
return ret;
}
/* =Search-Entry========================================================== */
struct ldb_context *ldb,
const char *filter,
const char **attrs,
struct ldb_message ***_msgs)
{
struct ldb_result *res;
int ret;
goto done;
}
goto done;
}
goto done;
}
done:
return ret;
}
const char *filter,
const char **attrs,
struct ldb_message ***_msgs)
{
return ret;
}
attrs);
}
const char *filter,
const char **attrs,
struct ldb_message ***_msgs)
{
if (_msgs_count != NULL) {
*_msgs_count = 0;
}
}
return EOK;
}
}
/* =Search-Entry-by-SID-string============================================ */
struct sss_domain_info *domain,
const char *search_base,
const char *filter_str,
const char *sid_str,
const char **attrs,
struct ldb_message **msg)
{
size_t msgs_count = 0;
char *filter;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto done;
}
if (!filter) {
goto done;
}
&msgs);
if (ret) {
goto done;
}
done:
}
else if (ret) {
}
return ret;
}
enum sysdb_obj_type {
SYSDB_UNKNOWN = 0,
};
struct sss_domain_info *domain,
const char *name,
enum sysdb_obj_type type,
const char **attrs,
struct ldb_message **msg)
{
const char *filter_tmpl = NULL;
size_t msgs_count = 0;
char *sanitized_name;
char *lc_sanitized_name;
char *filter;
int ret;
switch (type) {
case SYSDB_USER:
break;
case SYSDB_GROUP:
break;
default:
return EINVAL;
}
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto done;
}
goto done;
}
if (!filter) {
goto done;
}
&msgs_count, &msgs);
if (ret) {
goto done;
}
}
done:
}
else if (ret) {
}
return ret;
}
struct sss_domain_info *domain,
const char *name,
const char **attrs,
struct ldb_message **msg)
{
}
struct sss_domain_info *domain,
const char **attrs,
struct ldb_message **msg)
{
size_t msgs_count = 0;
char *filter;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto done;
}
if (!filter) {
goto done;
}
/* Use SUBTREE scope here, not ONELEVEL
* There is a bug in LDB that makes ONELEVEL searches extremely
* slow (it ignores indexing)
*/
if (ret) {
goto done;
}
done:
}
else if (ret) {
}
return ret;
}
struct sss_domain_info *domain,
const char *sid_str,
const char **attrs,
struct ldb_message **msg)
{
}
struct sss_domain_info *domain,
const char *upn,
const char **attrs,
struct ldb_result **out_res)
{
struct ldb_result *res;
int ret;
SYSDB_USER_EMAIL, NULL };
goto done;
}
goto done;
}
goto done;
}
/* set result anyway */
goto done;
"Search for upn [%s] returns more than one result.\n", upn);
goto done;
}
/* Merge in the timestamps from the fast ts db */
/* non-fatal */
}
done:
return ret;
}
struct sss_domain_info *domain,
const char *upn,
const char **attrs,
struct ldb_message **msg)
{
struct ldb_result *res;
goto done;
}
goto done;
goto done;
}
done:
return ret;
}
struct sss_domain_info *domain,
const char *name,
const char **attrs,
struct ldb_message **msg)
{
}
struct sss_domain_info *domain,
const char **attrs,
struct ldb_message **msg)
{
size_t msgs_count = 0;
char *filter;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto done;
}
if (!filter) {
goto done;
}
/* Use SUBTREE scope here, not ONELEVEL
* There is a bug in LDB that makes ONELEVEL searches extremely
* slow (it ignores indexing)
*/
&msgs_count, &msgs);
if (ret) {
goto done;
}
done:
}
else if (ret) {
}
return ret;
}
struct sss_domain_info *domain,
const char *sid_str,
const char **attrs,
struct ldb_message **msg)
{
}
/* =Search-Group-by-Name============================================ */
struct sss_domain_info *domain,
const char *name,
const char **attrs,
struct ldb_message **msg)
{
size_t msgs_count = 0;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto done;
}
&msgs);
if (ret) {
goto done;
}
done:
}
else if (ret) {
}
return ret;
}
/* =Timestamp-cache-functions==============================================*/
/* If modifyTimestamp is the same in the TS cache, return EOK. Return ERR_NO_TS
* if there is no timestamps cache for this domain and ERR_TS_CACHE_MISS if
* the entry had changed and the caller needs to update the sysdb cache as well.
*/
struct sysdb_attrs *entry)
{
struct ldb_message **msgs;
bool mod_ts_differs;
return ERR_NO_TS;
}
return ENOMEM;
}
/* Check if the entry is in the timestamp cache */
NULL,
&msgs);
"Cannot find TS cache entry for [%s]: [%d]: %s\n",
goto done;
}
if (msgs_count != 1) {
"Expected 1 result for base search, got %zu\n", msgs_count);
return EIO;
}
if (mod_ts_differs == true) {
goto done;
}
done:
return ret;
}
struct sysdb_attrs *attrs,
int mod_op);
struct sysdb_attrs *attrs)
{
struct ldb_message *msg;
int lret;
return EOK;
}
return ENOMEM;
}
goto done;
}
goto done;
}
if (lret != LDB_SUCCESS) {
"ldb_add failed: [%s](%d)[%s]\n",
}
done:
} else if (ret) {
}
return ret;
}
enum sysdb_obj_type obj_type)
{
struct sysdb_attrs *attrs;
const char *oc;
switch (obj_type) {
case SYSDB_USER:
break;
case SYSDB_GROUP:
break;
default:
return NULL;
}
return NULL;
}
return NULL;
}
return attrs;
}
struct sysdb_attrs *entry_attrs,
struct sysdb_attrs *ts_attrs,
int mod_op,
{
const char *modstamp;
return EOK;
}
return ENOMEM;
}
goto done;
}
}
"Failed to add %s to tsdb\n", SYSDB_LAST_UPDATE);
goto done;
}
((cache_timeout) ?
(now + cache_timeout) : 0));
"Failed to add %s to tsdb\n", SYSDB_CACHE_EXPIRE);
goto done;
}
if (entry_attrs != NULL) {
&modstamp);
"Failed to add %s to tsdb\n", SYSDB_ORIG_MODSTAMP);
goto done;
}
}
}
"Cannot set ts attrs for group %s\n",
/* Not fatal */
}
done:
return ret;
}
struct sysdb_attrs *attrs,
{
switch (ret) {
case ENOENT:
break;
case EOK:
/* The entry's timestamp was the same. Just update the ts cache */
"Cannot update the timestamps cache [%d]: %s\n",
}
break;
case ERR_TS_CACHE_MISS:
case ERR_NO_TS:
/* Either there is no cache or the cache is up-do-date. Just report
* what's up
*/
break;
default:
"Error checking the timestamps cache [%d]: %s\n",
break;
}
return ret;
}
struct sss_domain_info *domain,
enum sysdb_obj_type obj_type,
const char *obj_name,
{
switch (obj_type) {
case SYSDB_USER:
break;
case SYSDB_GROUP:
break;
default:
return EINVAL;
}
return ENOMEM;
}
return EOK;
}
enum sysdb_obj_type obj_type,
const char *obj_name,
struct sysdb_attrs *attrs,
{
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
cache_timeout, now);
done:
return ret;
}
enum sysdb_obj_type obj_type,
const char *obj_name,
{
return EOK;
}
return ENOMEM;
}
goto done;
}
goto done;
}
goto done;
}
done:
return ret;
}
const char *grp_name,
struct sysdb_attrs *attrs,
{
}
const char *grp_name,
{
cache_timeout, now);
}
const char *usr_name,
{
cache_timeout, now);
}
/* =Replace-Attributes-On-Entry=========================================== */
struct sysdb_attrs *attrs,
int mod_op)
{
struct ldb_message *msg;
int ret;
int lret;
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
goto done;
}
if (lret != LDB_SUCCESS) {
"ldb_modify failed: [%s](%d)[%s]\n",
}
done:
}
else if (ret) {
}
return ret;
}
struct sysdb_attrs *attrs,
int mod_op)
{
bool sysdb_write = true;
if (sysdb_write == true) {
"Cannot set attrs for %s, %d [%s]\n",
}
}
/* Not fatal */
}
}
return ret;
}
struct sysdb_attrs *attrs)
{
return EOK;
}
}
struct sysdb_attrs *attrs,
int mod_op)
{
struct sysdb_attrs *ts_attrs;
return EOK;
}
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
switch (mod_op) {
case SYSDB_MOD_REP:
break;
case SYSDB_MOD_ADD:
break;
default:
break;
}
done:
return ret;
}
/* =Replace-Attributes-On-User============================================ */
const char *name,
struct sysdb_attrs *attrs,
int mod_op)
{
if (!tmp_ctx) {
return ENOMEM;
}
if (!dn) {
goto done;
}
goto done;
}
done:
return ret;
}
/* =Replace-Attributes-On-Group=========================================== */
const char *name,
struct sysdb_attrs *attrs,
int mod_op)
{
if (!tmp_ctx) {
goto done;
}
if (!dn) {
goto done;
}
if (ret) {
goto done;
}
done:
return ret;
}
/* =Replace-Attributes-On-Netgroup=========================================== */
const char *name,
struct sysdb_attrs *attrs,
int mod_op)
{
if (!tmp_ctx) {
return ENOMEM;
}
if (!dn) {
goto done;
}
done:
return ret;
}
/* =Get-New-ID============================================================ */
{
char *filter;
struct ldb_message **msgs;
struct ldb_message *msg;
int ret;
int i;
if (!tmp_ctx) {
return ENOMEM;
}
if (!base_dn) {
return ENOMEM;
}
if (ret) {
return ret;
}
switch (ret) {
case EOK:
goto done;
}
}
"Failed to allocate new id, out of range (%u/%u)\n",
goto done;
}
break;
case ENOENT:
/* looks like the domain is not initialized yet, use min_id */
break;
default:
goto done;
}
count = 0;
/* verify the id is actually really free.
* search all entries with id >= new_id and < max_id */
"(|(&(%s>=%u)(%s<=%u))(&(%s>=%u)(%s<=%u)))",
}
else {
"(|(%s>=%u)(%s>=%u))",
}
if (!filter) {
goto done;
}
switch (ret) {
/* if anything was found, find the maximum and increment past it */
case EOK:
for (i = 0; i < count; i++) {
}
}
}
new_id++;
/* check again we are not falling out of range */
"Failed to allocate new id, out of range (%u/%u)\n",
goto done;
}
break;
case ENOENT:
break;
default:
goto done;
}
count = 0;
/* finally store the new next id */
if (!msg) {
goto done;
}
if (ret) {
goto done;
}
if (ret != LDB_SUCCESS) {
"ldb_modify failed: [%s](%d)[%s]\n",
}
done:
} else {
}
if (ret) {
}
return ret;
}
/* =Add-Basic-User-NO-CHECKS============================================== */
const char *name,
const char *gecos,
const char *homedir,
const char *shell)
{
struct ldb_message *msg;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!msg) {
goto done;
}
/* user dn */
}
/* We set gecos to be the same as fullname on user creation,
* But we will not enforce coherency after that, it's up to
* admins to decide if they want to keep it in sync if they change
* one of the 2 */
}
}
}
/* creation time */
done:
if (ret) {
}
return ret;
}
static errno_t
struct ldb_message *group,
struct ldb_message_element *alias_el,
const char *name,
const char *orig_dn,
const char *userdn)
{
struct ldb_message *msg;
struct ldb_message_element *orig_members;
bool add_member = false;
int i;
if (!tmp_ctx) {
return ENOENT;
}
if (!msg) {
}
/* We have no way of telling which groups this user belongs to.
* Add it to all that reference it in the ghost attribute */
add_member = true;
} else {
add_member = false;
if (orig_members) {
for (i = 0; i < orig_members->num_values; i++) {
orig_dn) == 0) {
/* This is a direct member. Add the member attribute */
add_member = true;
}
}
} else {
/* Nothing to compare the originalDN with. Let's rely on the
* memberof plugin to do the right thing during initgroups..
*/
add_member = true;
}
}
if (add_member) {
}
/* Delete aliases from the ghost attribute as well */
for (i = 0; i < alias_el->num_values; i++) {
continue;
}
if (ret != LDB_SUCCESS) {
}
}
if (ret != LDB_SUCCESS) {
"sss_ldb_modify_permissive failed: [%s](%d)[%s]\n",
}
goto done;
}
done:
return ret;
}
static errno_t
const char *orig_dn,
struct sysdb_attrs *attrs,
const char *name)
{
struct ldb_message **groups;
struct ldb_message_element *alias_el;
const char *userdn;
char *sanitized_name;
char *filter;
size_t group_count = 0;
int i;
if (!tmp_ctx) {
return ENOENT;
}
goto done;
}
if (!filter) {
goto done;
}
goto done;
}
for (i = 0; i < alias_el->num_values; i++) {
continue;
}
goto done;
}
}
goto done;
}
if (!tmpdn) {
}
if (!userdn) {
}
/* To cover cross-domain group-membership we must search in all
* sub-domains. */
if (!tmpdn) {
goto done;
}
/* We need to find all groups that contain this object as a ghost user
* and replace the ghost user by actual member record in direct parents.
* Note that this object can be referred to either by its name or any
* of its aliases
*/
goto done;
}
for (i = 0; i < group_count; i++) {
}
done:
return ret;
}
/* =Add-User-Function===================================================== */
const char *name,
const char *gecos,
const char *homedir,
const char *shell,
const char *orig_dn,
struct sysdb_attrs *attrs,
int cache_timeout,
{
struct ldb_message *msg;
struct sysdb_attrs *id_attrs;
int ret;
if (gid != 0) {
"Cannot add user with arbitrary GID in MPG domain!\n");
return EINVAL;
}
}
return ERANGE;
}
return ERANGE;
}
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* In MPG domains you can't have groups with the same name as users,
* search if a group with the same name exists.
* Don't worry about users, if we try to add a user with the same
* name the operation will fail */
goto done;
}
}
/* check no other user with the same uid exist */
if (uid != 0) {
goto done;
}
}
/* try to add the user */
"Cannot create user timestamp entry\n");
/* Not fatal */
}
if (uid == 0) {
if (!id_attrs) {
goto done;
}
}
/* continue on success, to commit additional attrs */
}
if (!attrs) {
if (!attrs) {
goto done;
}
}
if (!now) {
}
((cache_timeout) ?
(now + cache_timeout) : 0));
/* If we're not enumerating, previous getgr{nam,gid} calls might
* have stored ghost users into the cache, so we need to link them
* with the newly-created user entry
*/
name);
}
done:
} else {
}
return ret;
}
/* =Add-Basic-Group-NO-CHECKS============================================= */
{
struct ldb_message *msg;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!msg) {
goto done;
}
/* group dn */
}
/* creation time */
done:
if (ret) {
}
return ret;
}
/* =Add-Group-Function==================================================== */
struct sysdb_attrs *attrs,
int cache_timeout,
{
struct ldb_message *msg;
int ret;
bool posix;
return ERANGE;
}
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* In MPG domains you can't have groups with the same name as users,
* search if a group with the same name exists.
* Don't worry about users, if we try to add a user with the same
* name the operation will fail */
"with the same name - %s.\n", name);
} else {
"sysdb_search_user_by_name failed for user %s.\n", name);
}
goto done;
}
}
/* check no other groups with the same gid exist */
if (gid != 0) {
} else {
"sysdb_search_group_by_gid failed for gid: "
}
goto done;
}
}
/* try to add the group */
if (ret) {
"sysdb_add_basic_group failed for: %s with gid: "
goto done;
}
"Cannot set timestamp cache attributes for a group\n");
/* Not fatal */
}
if (!attrs) {
if (!attrs) {
goto done;
}
}
posix = true;
if (ret) {
goto done;
}
goto done;
}
if (ret) {
goto done;
}
if (ret) {
goto done;
}
}
if (!now) {
}
if (ret) {
goto done;
}
((cache_timeout) ?
(now + cache_timeout) : 0));
if (ret) {
goto done;
}
if (ret) {
goto done;
}
done:
} else {
}
return ret;
}
const char *name,
const char *original_dn,
const char *sid_str,
const char *uuid,
bool posix,
{
int ret;
struct sysdb_attrs *attrs;
if (!tmp_ctx) {
return ENOMEM;
}
/* try to add the group */
if (!now) {
}
"Cannot set timestamp cache attributes for a group\n");
/* Not fatal */
}
if (!attrs) {
goto done;
}
now-1);
if (original_dn) {
}
if (sid_str) {
}
if (uuid) {
}
done:
}
return ret;
}
/* =Add-Or-Remove-Group-Memeber=========================================== */
/* mod_op must be either SYSDB_MOD_ADD or SYSDB_MOD_DEL */
int mod_op)
{
struct ldb_message *msg;
const char *dn;
int ret;
if (!msg) {
}
if (ret != LDB_SUCCESS) {
}
if (!dn) {
}
if (ret != LDB_SUCCESS) {
}
if (ret != LDB_SUCCESS) {
"ldb_modify failed: [%s](%d)[%s]\n",
}
fail:
if (ret) {
}
return ret;
}
/* =Add-Basic-Netgroup-NO-CHECKS============================================= */
const char *name, const char *description)
{
struct ldb_message *msg;
int ret;
if (!msg) {
return ENOMEM;
}
/* netgroup dn */
}
if (description && *description) {
}
/* creation time */
done:
if (ret) {
}
return ret;
}
/* =Add-Netgroup-Function==================================================== */
const char *name,
const char *description,
struct sysdb_attrs *attrs,
char **missing,
int cache_timeout,
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* try to add the netgroup */
if (!attrs) {
if (!attrs) {
goto done;
}
}
if (!now) {
}
((cache_timeout) ?
(now + cache_timeout) : 0));
if (missing) {
missing);
}
}
done:
}
}
return ret;
}
const char *name,
const char *gecos,
const char *homedir,
const char *shell,
const char *orig_dn,
struct sysdb_attrs *attrs,
const char *name,
const char *gecos,
const char *homedir,
const char *shell,
const char *orig_dn,
struct sysdb_attrs *attrs,
char **remove_attrs,
/* if one of the basic attributes is empty ("") as opposed to NULL,
* this will just remove it */
const char *name,
const char *pwd,
const char *gecos,
const char *homedir,
const char *shell,
const char *orig_dn,
struct sysdb_attrs *attrs,
char **remove_attrs,
{
struct ldb_message *msg;
int ret;
bool in_transaction = false;
/* get transaction timestamp */
if (now == 0) {
}
if (!tmp_ctx) {
return ENOMEM;
}
if (!attrs) {
if (!attrs) {
goto done;
}
}
}
goto done;
}
in_transaction = true;
goto done;
}
}
/* the user doesn't exist, turn into adding a user */
} else {
/* the user exists, let's just replace attributes when set */
cache_timeout, now);
}
goto done;
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
if (ret) {
}
return ret;
}
const char *name,
const char *gecos,
const char *homedir,
const char *shell,
const char *orig_dn,
struct sysdb_attrs *attrs,
{
/* This may be a user rename. If there is a user with the
* same UID, remove it and try to add the basic user again
*/
/* Not found by UID, return the original EEXIST,
* this may be a conflict in MPG domain or something
* else */
return EEXIST;
return ret;
}
"A user with the same UID [%llu] was removed from the "
"cache\n", (unsigned long long) uid);
if (ret) {
"sysdb_add_user failed (while renaming user) for: "
return ret;
}
}
return EOK;
}
const char *name,
const char *gecos,
const char *homedir,
const char *shell,
const char *orig_dn,
struct sysdb_attrs *attrs,
char **remove_attrs,
{
if (uid) {
}
if (gid) {
}
}
if (gecos) {
}
if (homedir) {
}
if (shell) {
}
((cache_timeout) ?
(now + cache_timeout) : 0));
if (remove_attrs) {
"Could not remove missing attributes\n");
}
}
return EOK;
}
/* this function does not check that all user members are actually present */
const char *name,
struct sysdb_attrs *attrs,
const char *name,
struct sysdb_attrs *attrs,
const char *name,
struct sysdb_attrs *attrs,
{
struct ldb_message *msg;
bool new_group = false;
int ret;
bool in_transaction = false;
/* get transaction timestamp */
if (!now) {
}
cache_timeout, now);
"The group record of %s did not change, only updated "
"the timestamp cache\n", name);
return EOK;
}
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
in_transaction = true;
"sysdb_search_group_by_name failed for %s with: [%d][%s].\n",
goto done;
}
new_group = true;
}
if (!attrs) {
if (!attrs) {
goto done;
}
}
if (new_group) {
cache_timeout, now);
} else {
cache_timeout, now);
}
goto done;
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
if (ret) {
}
return ret;
}
const char *name,
struct sysdb_attrs *attrs,
{
/* group doesn't exist, turn into adding a group */
/* This may be a group rename. If there is a group with the
* same GID, remove it and try to add the basic group again
*/
/* Not found by GID, return the original EEXIST,
* this may be a conflict in MPG domain or something
* else */
"sysdb_delete_group failed (while renaming group). Not "
return EEXIST;
return ret;
}
"the cache\n", gid);
if (ret) {
"sysdb_add_group failed (while renaming group) for: "
return ret;
}
}
return EOK;
}
const char *name,
struct sysdb_attrs *attrs,
{
/* the group exists, let's just replace attributes when set */
if (gid) {
if (ret) {
return ret;
}
}
if (ret) {
return ret;
}
((cache_timeout) ?
(now + cache_timeout) : 0));
if (ret) {
return ret;
}
if (ret) {
return ret;
}
return EOK;
}
static int
const char *group,
const char *member,
enum sysdb_member_type type,
int modify_op,
bool is_dn)
{
char *member_domname;
struct sss_domain_info *member_dom;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
NULL, &member_domname);
"Failed to parser internal fqname '%s' [%d]: %s\n",
goto done;
}
member_domname, false);
if (member_dom == NULL) {
"Domain [%s] was not found\n", member_domname);
goto done;
}
if (type == SYSDB_MEMBER_USER) {
} else if (type == SYSDB_MEMBER_GROUP) {
} else {
goto done;
}
if (!member_dn) {
goto done;
}
if (!is_dn) {
} else {
}
if (!group_dn) {
goto done;
}
done:
return ret;
}
const char *group,
const char *member,
enum sysdb_member_type type,
bool is_dn)
{
}
const char *group,
const char *member,
enum sysdb_member_type type,
bool is_dn)
{
}
/* =Password-Caching====================================================== */
const char *username,
const char *password,
enum sss_authtok_type authtok_type,
{
struct sysdb_attrs *attrs;
char *salt;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
goto fail;
}
if (ret) {
goto fail;
}
if (!attrs) {
}
}
/* FIXME: should we use a different attribute for chache passwords ?? */
if (ret) {
goto fail;
}
return EOK;
fail:
if (ret) {
}
return ret;
}
const char *username,
const char *password)
{
}
/* =Custom Search================== */
struct sss_domain_info *domain,
const char *filter,
const char *subtree_name,
const char **attrs,
struct ldb_message ***msgs)
{
int ret;
goto done;
}
goto done;
}
goto done;
}
if (!ldb_dn_validate(basedn)) {
goto done;
}
msgs_count, msgs);
done:
return ret;
}
struct sss_domain_info *domain,
const char *object_name,
const char *subtree_name,
const char **attrs,
struct ldb_message ***_msgs)
{
struct ldb_message **msgs;
int ret;
return EINVAL;
}
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
if (!ldb_dn_validate(basedn)) {
goto done;
}
if (ret) {
goto done;
}
if (count > 1) {
goto done;
}
done:
return ret;
}
/* =Custom Store (replaces-existing-data)================== */
const char *object_name,
const char *subtree_name,
struct sysdb_attrs *attrs)
{
size_t resp_count = 0;
struct ldb_message **resp;
struct ldb_message *msg;
struct ldb_message_element *el;
bool add_object = false;
int ret;
int i;
return EINVAL;
}
if (ret) {
return sysdb_error_to_errno(ret);
}
if (!tmp_ctx) {
goto done;
}
goto done;
}
add_object = true;
}
goto done;
}
goto done;
}
goto done;
}
if (add_object) {
} else {
} else {
}
}
}
if (add_object) {
} else {
}
if (ret != LDB_SUCCESS) {
}
done:
if (ret) {
} else {
}
return ret;
}
/* = Custom Delete======================================= */
const char *object_name,
const char *subtree_name)
{
int ret;
return EINVAL;
}
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
switch (ret) {
case LDB_SUCCESS:
case LDB_ERR_NO_SUCH_OBJECT:
break;
default:
break;
}
done:
return ret;
}
/* = ASQ search request ======================================== */
struct sss_domain_info *domain,
const char *expression,
const char *asq_attribute,
const char **attrs,
struct ldb_message ***msgs)
{
struct ldb_request *ldb_req;
struct ldb_control **ctrl;
struct ldb_asq_control *asq_control;
struct ldb_result *res;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
goto fail;
}
goto fail;
}
if (asq_control == NULL) {
goto fail;
}
goto fail;
}
if (!res) {
goto fail;
}
if (ret != LDB_SUCCESS) {
goto fail;
}
if (ret == LDB_SUCCESS) {
}
if (ret) {
goto fail;
}
return EOK;
fail:
}
else if (ret) {
}
return ret;
}
/* =Search-Users-with-Custom-Filter====================================== */
struct sss_domain_info *domain,
struct ldb_context *ldb,
const char *sub_filter,
const char **attrs,
struct ldb_message ***msgs)
{
char *filter;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto fail;
}
if (!filter) {
goto fail;
}
"Search users with filter: %s\n", filter);
msgs_count, msgs);
if (ret) {
goto fail;
}
return EOK;
fail:
}
else if (ret) {
}
return ret;
}
struct sss_domain_info *domain,
const char *sub_filter,
const char **attrs,
struct ldb_message ***msgs)
{
return ret;
}
attrs);
}
struct sss_domain_info *domain,
const char *sub_filter,
const char **attrs,
struct ldb_result *res)
{
struct ldb_message **msgs;
int ret;
return EINVAL;
}
ZERO_STRUCT(*res);
return ENOENT;
}
}
return ret;
}
/* =Delete-User-by-Name-OR-uid============================================ */
{
char *filter;
struct ldb_message **msgs;
struct ldb_message *msg;
int ret;
int i;
char *sanitized_name;
if (!tmp_ctx) {
return ENOMEM;
}
if (name) {
} else {
}
const char *c_name;
"Attribute is missing but this should never happen!\n");
goto fail;
}
/* this is not the entry we are looking for */
goto fail;
}
}
if (ret) {
goto fail;
}
/* Perhaps a ghost user? */
goto fail;
}
goto fail;
}
goto fail;
}
for (i = 0; i < msg_count; i++) {
if (!msg) {
}
if (ret != LDB_SUCCESS) {
"ldb_modify failed: [%s](%d)[%s]\n",
}
goto fail;
}
}
} else {
goto fail;
}
return EOK;
fail:
return ret;
}
/* =Search-Groups-with-Custom-Filter===================================== */
struct sss_domain_info *domain,
struct ldb_context *ldb,
const char *sub_filter,
const char **attrs,
struct ldb_message ***msgs)
{
char *filter;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto fail;
}
if (!filter) {
goto fail;
}
"Search groups with filter: %s\n", filter);
msgs_count, msgs);
if (ret) {
goto fail;
}
return EOK;
fail:
}
else if (ret) {
}
return ret;
}
struct sss_domain_info *domain,
const char *sub_filter,
const char **attrs,
struct ldb_message ***msgs)
{
return ret;
}
attrs);
}
struct sss_domain_info *domain,
const char *sub_filter,
const char **attrs,
struct ldb_result *res)
{
struct ldb_message **msgs;
int ret;
return EINVAL;
}
ZERO_STRUCT(*res);
return ENOENT;
}
}
return ret;
}
/* =Delete-Group-by-Name-OR-gid=========================================== */
{
struct ldb_message *msg;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (name) {
} else {
}
if (ret) {
goto fail;
}
const char *c_name;
"Attribute is missing but this should never happen!\n");
goto fail;
}
/* this is not the entry we are looking for */
goto fail;
}
}
if (ret) {
goto fail;
}
return EOK;
fail:
return ret;
}
/* =Search-Netgroups-with-Custom-Filter===================================== */
struct sss_domain_info *domain,
const char *sub_filter,
const char **attrs,
struct ldb_message ***msgs)
{
char *filter;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (!basedn) {
goto fail;
}
if (!filter) {
goto fail;
}
msgs_count, msgs);
if (ret) {
goto fail;
}
return EOK;
fail:
} else {
}
return ret;
}
/* =Delete-Netgroup-by-Name============================================== */
const char *name)
{
struct ldb_message *msg;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
"sysdb_search_netgroup_by_name failed: %d (%s)\n",
goto done;
"Netgroup does not exist, nothing to delete\n");
goto done;
}
goto done;
}
done:
}
return ret;
}
struct sss_domain_info *domain,
const char *sid_str)
{
struct ldb_result *res;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
/* No existing entry. Just quit. */
"search by sid did not return any results.\n");
goto done;
goto done;
}
"result !?!\n");
goto done;
}
goto done;
}
done:
}
return ret;
}
/* ========= Authentication against cached password ============ */
struct ldb_message *ldb_msg,
{
int ret;
int failed_login_delay;
if (!tmp_ctx) {
return ENOMEM;
}
*delayed_until = -1;
"Failed to read the number of allowed failed login "
"attempts.\n");
ret = ERR_INTERNAL;
goto done;
}
ret = ERR_INTERNAL;
goto done;
}
"Failed login attempts [%d], allowed failed login attempts [%d], "
"failed login delay [%d].\n", *failed_login_attempts,
if (failed_login_delay) {
"resetting failed_login_attempts.\n");
*failed_login_attempts = 0;
} else {
"login delayed until %lld.\n", (long long) end);
*delayed_until = end;
goto done;
}
} else {
goto done;
}
}
}
done:
return ret;
}
struct ldb_message *ldb_msg,
const char *password,
const char *userhash)
{
unsigned int cached_authtok_type;
unsigned int cached_fa2_len;
char *short_pw;
char *comphash;
int ret;
if (cached_authtok_type != SSS_AUTHTOK_TYPE_2FA) {
return EINVAL;
}
0);
if (cached_fa2_len == 0) {
return EINVAL;
}
return EINVAL;
}
return ENOMEM;
}
goto done;
}
ret = ERR_INTERNAL;
goto done;
}
"Hash of shorten password does not match.\n");
goto done;
}
done:
return ret;
}
const char *name,
const char *password,
struct confdb_ctx *cdb,
bool just_check,
{
"lastCachedPasswordChange",
"accountExpires", SYSDB_FAILED_LOGIN_ATTEMPTS,
struct ldb_message *ldb_msg;
const char *userhash;
char *comphash;
int cred_expiration;
struct sysdb_attrs *update_attrs;
bool authentication_successful = false;
int ret;
return EINVAL;
}
return EINVAL;
}
return EINVAL;
}
if (!domain->cache_credentials) {
return EINVAL;
}
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
"sysdb_search_user_by_name failed [%d][%s].\n",
goto done;
}
/* Check offline_auth_cache_timeout */
0);
"Failed to read expiration time of offline credentials.\n");
goto done;
}
if (cred_expiration) {
expire_date = 0;
goto done;
}
} else {
expire_date = 0;
}
goto done;
}
/* TODO: verify user account (disabled, expired ...) */
goto done;
}
if (ret) {
ret = ERR_INTERNAL;
goto done;
}
if (update_attrs == NULL) {
goto done;
}
/* TODO: probable good point for audit logging */
authentication_successful = true;
if (just_check) {
goto done;
}
"but authentication is successful.\n");
goto done;
}
"but authentication is successful.\n");
goto done;
}
} else {
authentication_successful = false;
goto done;
}
goto done;
}
}
if (ret) {
"Failed to update Login attempt information!\n");
}
done:
if (_expire_date != NULL) {
}
if (_delayed_until != NULL) {
}
if (ret) {
} else {
if (ret) {
}
}
if (authentication_successful) {
} else {
}
}
return ret;
}
const char *member,
enum sysdb_member_type type,
const char *const *add_groups,
const char *const *del_groups,
bool is_dn)
{
int i;
bool in_transaction = false;
if(!tmp_ctx) {
return ENOMEM;
}
goto done;
}
in_transaction = true;
if (add_groups) {
/* Add the user to all add_groups */
for (i = 0; add_groups[i]; i++) {
"Could not add member [%s] to group [%s]. "
/* Continue on, we should try to finish the rest */
}
}
}
if (del_groups) {
/* Remove the user from all del_groups */
for (i = 0; del_groups[i]; i++) {
"Could not remove member [%s] from group [%s]. "
/* Continue on, we should try to finish the rest */
}
}
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
const char *member,
enum sysdb_member_type type,
const char *const *add_groups,
const char *const *del_groups)
{
add_groups, del_groups, false);
}
const char *member,
enum sysdb_member_type type,
const char *const *add_groups,
const char *const *del_groups)
{
add_groups, del_groups, true);
}
const char *name,
enum sysdb_member_type type,
char **remove_attrs)
{
bool in_transaction = false;
struct ldb_message *msg;
int lret;
size_t i;
switch(type) {
case SYSDB_MEMBER_USER:
break;
case SYSDB_MEMBER_GROUP:
break;
case SYSDB_MEMBER_NETGROUP:
break;
case SYSDB_MEMBER_SERVICE:
break;
}
goto done;
}
goto done;
}
in_transaction = true;
for (i = 0; remove_attrs[i]; i++) {
/* SYSDB_MEMBEROF is exclusively handled by the memberof plugin */
continue;
}
remove_attrs[i], name);
if (lret != LDB_SUCCESS) {
goto done;
}
/* We need to do individual modifies so that we can
* skip unknown attributes. Otherwise, any nonexistent
* attribute in the sysdb will cause other removals to
* fail.
*/
"ldb_modify failed: [%s](%d)[%s]\n",
goto done;
}
/* Remove this attribute and move on to the next one */
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
struct sss_domain_info *domain,
const char *filter_tmpl,
const char *str,
const char **attrs,
struct ldb_result **_res)
{
NULL };
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
filter_tmpl, str);
goto done;
}
"returned more than one object.\n",
str, filter_tmpl);
goto done;
goto done;
}
/* Merge in the timestamps from the fast ts db */
/* non-fatal */
}
done:
} else if (ret) {
}
return ret;
}
struct sss_domain_info *domain,
const char *sid_str,
const char **attrs,
struct ldb_result **res)
{
}
struct sss_domain_info *domain,
const char *uuid_str,
const char **attrs,
struct ldb_result **res)
{
}
struct sss_domain_info *domain,
const char *cert,
const char **attrs,
struct ldb_result **res)
{
int ret;
char *user_filter;
&user_filter);
return ret;
}
return ret;
}
struct sss_domain_info *domain,
const char *cert,
struct ldb_result **res)
{
const char *user_attrs[] = SYSDB_PW_ATTRS;
}
const char *cert)
{
unsigned int i;
goto done;
goto done;
}
/* Certificate may be found on more objects, remove it from all.
* If object contains more then one certificate, we still remove the
* whole attribute since it will be downloaded again. */
goto done;
}
continue;
}
}
done:
return ret;
}
struct sss_domain_info *dom,
const char *group_name,
const char ***_sids,
const char ***_dns,
{
struct ldb_message *msg;
struct ldb_message **members;
size_t n = 0;
return ENOMEM;
}
goto done;
}
/* Get sid_str attribute of all elemets pointed to by group members */
goto done;
}
goto done;
}
goto done;
}
for (i=0; i < m_count; i++) {
const char *sidstr;
goto done;
}
n++;
}
}
if (n == 0) {
goto done;
}
*_n = n;
done:
} else if (ret) {
}
return ret;
}
struct sss_domain_info *dom,
struct ldb_result **members)
{
int ret;
struct ldb_result *res;
char *filter;
char *sanitized_name;
const char *attrs[] = SYSDB_PW_ATTRS;
struct ldb_message **msgs;
return ENOMEM;
}
goto done;
}
"Failed to sanitize the given name:'%s'.\n",
goto done;
}
goto done;
}
goto done;
}
goto done;
}
done:
} else {
}
return ret;
}
struct sysdb_attrs *src_attrs,
const char *src_name,
struct sysdb_attrs *dest_attrs,
const char *dest_name)
{
int ret;
struct ldb_message_element *el;
char guid_str_buf[GUID_STR_BUF_SIZE];
/* This provider doesn't handle UUIDs */
return ENOENT;
}
return EINVAL;
}
}
return ret;
}
"Found more than one UUID value, using the first.\n");
}
/* Check if we got a binary AD objectGUID */
return ret;
}
} else {
}
return ret;
}
return EOK;
}
/* Mark entry as expired */
{
struct ldb_message *msg;
return ENOMEM;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
done:
return ret;
}
{
return ENOMEM;
}
goto done;
}
done:
return ret;
}