/*
SSSD
Authors:
Simo Sorce <ssorce@redhat.com>
Stephen Gallagher <sgallagh@redhat.com>
Copyright (C) 2008-2011 Simo Sorce <ssorce@redhat.com>
Copyright (C) 2008-2011 Stephen Gallagher
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_autofs.h"
struct upgrade_ctx {
const char *new_version;
};
{
int ret;
if (!ctx) {
return ENOMEM;
}
if (ret != LDB_SUCCESS) {
goto done;
}
done:
} else {
}
return ret;
}
{
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
done:
return ret;
}
{
int lret;
}
}
if (lret != LDB_SUCCESS) {
"Could not cancel transaction! [%s]\n",
ldb_strerror(lret));
/* Do not overwrite ret here, we want to return
* the original failure, not the failure of the
* transaction cancellation.
*/
}
}
talloc_zfree(*ctx);
return ret;
}
/* serach all groups that have a memberUid attribute.
* change it into a member attribute for a user of same domain.
* remove the memberUid attribute
* add the new member attribute
* finally stop indexing memberUid
* upgrade version to 0.2
*/
{
const char *mdn;
char *domain;
int ret, i, j;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
if (!basedn) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (!el) {
"memberUid is missing from message [%s], skipping\n",
continue;
}
/* create modification message */
if (!msg) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* get domain name component value */
if (!domain) {
goto done;
}
for (j = 0; j < el->num_values; j++) {
if (!mem_dn) {
goto done;
}
if (!mdn) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
}
/* ok now we are ready to modify the entry */
if (ret != LDB_SUCCESS) {
goto done;
}
}
/* conversion done, update version number */
done:
return ret;
}
const char *db_path)
{
char *ldb_file;
bool do_02_upgrade = false;
bool ctx_trans = false;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
db_path);
goto exit;
}
return ret;
}
if (!verdn) {
goto exit;
}
if (ret != LDB_SUCCESS) {
goto exit;
}
goto exit;
}
if (el) {
goto exit;
}
if (!version) {
goto exit;
}
/* all fine, return */
goto exit;
}
"Upgrading DB from version: %s\n", version);
/* convert database */
}
/* need to convert database to split files */
do_02_upgrade = true;
}
}
}
if (!do_02_upgrade) {
/* not a v2 upgrade, return and let the normal code take over any
* further upgrade */
goto exit;
}
/* == V2->V3 UPGRADE == */
"UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3);
/* ldb uses posix locks,
* posix is stupid and kills all locks when you close *any* file
* descriptor associated to the same file.
* Therefore we must close and reopen the ldb file here */
/* == Backup and reopen ldb == */
/* close */
/* backup*/
goto exit;
}
/* reopen */
return ret;
}
/* open a transaction */
if (ret != LDB_SUCCESS) {
"Failed to start ldb transaction! (%d)\n", ret);
goto exit;
}
/* == Upgrade contents == */
int i;
/* skip local */
continue;
}
/* create new dom db */
goto done;
}
if (ret != LDB_SUCCESS) {
"Failed to start ldb transaction! (%d)\n", ret);
goto done;
}
ctx_trans = true;
/* search all entries for this domain in local,
* copy them all in the new database,
* then remove them from local */
if (!domain_dn) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/*
* dom->sysdb->ldb is not initialized,
* so ldb_dn_new_fmt() shouldn't be changed to sysdb_*_base_dn()
*/
if (!users_dn) {
goto done;
}
/*
* dom->sysdb->ldb is not initialized,
* so ldb_dn_new_fmt() shouldn't be changed to sysdb_*_base_dn()
*/
if (!groups_dn) {
goto done;
}
/* skip pre-created congtainers */
continue;
}
/* regenerate the DN against the new ldb as it may have different
* casefolding rules (example: name changing from case insensitive
* to case sensitive) */
goto done;
}
if (ret != LDB_SUCCESS) {
" to new ldb file! (%d [%s])\n",
}
if (ret != LDB_SUCCESS) {
"WARNING: Could not remove entry %s,"
" from old ldb file! (%d [%s])\n",
}
}
/* now remove the basic containers from local */
/* these were optional so debug at level 9 in case
* of failure just for tracing */
if (ret != LDB_SUCCESS) {
" from old ldb file! (%d [%s])\n",
}
if (ret != LDB_SUCCESS) {
" from old ldb file! (%d [%s])\n",
}
if (ret != LDB_SUCCESS) {
" from old ldb file! (%d [%s])\n",
}
if (ret != LDB_SUCCESS) {
"Failed to commit ldb transaction! (%d)\n", ret);
goto done;
}
ctx_trans = false;
}
/* conversion done, upgrade version number */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
"Failed to commit ldb transaction! (%d)\n", ret);
goto exit;
}
done:
if (ctx_trans) {
if (ret != LDB_SUCCESS) {
"Failed to cancel ldb transaction! (%d)\n", ret);
}
}
if (ret != LDB_SUCCESS) {
"Failed to cancel ldb transaction! (%d)\n", ret);
}
}
exit:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Make this database case-sensitive */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Add new index */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* Rebuild memberuid and memberoif attributes */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Add new indexes */
if (!msg) {
goto done;
}
goto done;
}
/* Add Index for dataExpireTimestamp */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* Add index to speed up ONELEVEL searches */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Add new indexes */
if (!msg) {
goto done;
}
goto done;
}
/* Case insensitive search for originalDN */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Add new indexes */
if (!msg) {
goto done;
}
goto done;
}
/* Add Index for nameAlias */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Add new indexes */
if (!msg) {
goto done;
}
goto done;
}
/* Add Index for servicePort and serviceProtocol */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Add new indexes */
if (!msg) {
goto done;
}
goto done;
}
/* Add Index for servicePort and serviceProtocol */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
const char **ver)
{
int ret;
const char *name;
int i, j;
return ENOMEM;
}
if (ret) {
return ret;
}
/*
* dom->sysdb->ldb is not initialized,
* so ldb_dn_new_fmt() shouldn't be changed to sysdb_*_base_dn()
*/
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
goto done;
}
for (j = 0; j < memberof_el->num_values; j++) {
goto done;
}
goto done;
}
"upgrade: [%s]\n",
continue;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
/* If we failed adding the ghost user(s) because the values already
* exist, they were probably propagated from a parent that was
* upgraded before us. Mark the group as expired so that it is
* refreshed on next request.
*/
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
} else if (ret != LDB_SUCCESS) {
goto done;
}
}
if (ret != LDB_SUCCESS) {
goto done;
}
}
/* conversion done, update version number */
done:
return ret;
}
const char **ver)
{
const char *key;
const char *value;
NULL };
size_t i, j;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
for (j = 0; j < memberof_el->num_values; j++) {
&(memberof_el->values[j]));
if (!memberof_dn) {
continue;
}
if (!val) {
continue;
}
"Cannot save autofs entry [%s]-[%s] into map %s\n",
continue;
}
}
}
/* Delete the old entry if it was either processed or incomplete */
continue;
}
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* add new indexes */
if (!msg) {
goto done;
}
goto done;
}
/* add index for sshKnownHostsExpire */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
const char *tmp_str;
int i, j, l, n;
if (ret) {
return ret;
}
if (!basedn) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
"The object [%s] doesn't have a name\n",
continue;
}
if (!basedn) {
"Failed to build base dn for subdomain %s\n", tmp_str);
continue;
}
if (ret != LDB_SUCCESS) {
"Failed to search subdomain %s\n", tmp_str);
continue;
}
l = ldb_dn_get_comp_num(basedn);
if (n <= l + 1) {
/* Do not remove subdomain containers, only their contents */
continue;
}
if (ret) {
"Failed to delete %s\n",
continue;
}
}
}
/* conversion done, update version number */
done:
return ret;
}
{
const char *tmp_str;
int i;
if (ret) {
return ret;
}
if (!basedn) {
goto done;
}
/* create base ranges container */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* do a synchronous add */
if (ret != LDB_SUCCESS) {
"Failed to upgrade DB (%d, [%s])!\n",
goto done;
}
"objectclass=%s", SYSDB_ID_RANGE_CLASS);
if (ret != LDB_SUCCESS) {
goto done;
}
/* Failure to convert any range is not fatal. As long as there are no
* left-over objects we can fail to move them around, as they will be
* recreated on the next online access */
"The object [%s] doesn't have a name\n",
if (ret) {
"Failed to delete %s\n",
goto done;
}
continue;
}
if (!newdn) {
"Failed to create new DN to move [%s]\n",
goto done;
}
if (ret != LDB_SUCCESS) {
"Failed to move [%s] to [%s]\n",
if (ret) {
"Failed to delete %s\n",
goto done;
}
}
}
/* conversion done, update version number */
done:
return ret;
}
{
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret) {
return ret;
}
/* Add new indexes */
if (!msg) {
goto done;
}
goto done;
}
/* Case insensitive search for canonicalUserPrincipalName */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
{
if (ret) {
return ret;
}
goto done;
}
goto done;
}
/* add index for objectSIDString */
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* conversion done, update version number */
done:
return ret;
}
unsigned domain_index)
{
return NULL;
}
}
struct ldb_context *ldb,
struct ldb_message *msg,
const char *domain_attr,
unsigned domain_index)
{
if (domain_attr != NULL) {
} else {
/* If no specific attribute to take the domain from is specified,
* use the DN */
}
return NULL;
}
}
/* Used for attributes like sudoUser which contain group or user name or
* ID, depending on the value prefix */
/* Qualifies a string attribute using domain_name. Optionally, if qfn is
* given, only qualifies the name if qfn returns true */
struct ldb_message *mod_msg,
struct sss_names_ctx *names,
const char *domain_name,
const char *attrname,
{
char *fqval;
char *shortname;
const char *rawname;
int ret;
bool exists = false;
/* This entry does not have this element, fine */
return EOK;
}
continue;
}
"Cannot parse raw attribute %s\n", rawname);
continue;
}
continue;
}
return true;
}
}
if (!exists) {
if (ret != LDB_SUCCESS) {
continue;
}
exists = true;
}
if (ret != LDB_SUCCESS) {
continue;
}
}
return EOK;
}
/* Returns a copy of old_dn_val with RDN qualified. The domain name
* is read from the DN itself
*/
struct ldb_context *ldb,
struct sss_names_ctx *names,
struct ldb_dn *old_dn_val)
{
int ret;
return NULL;
}
/* Only qualify DNs with name= rdn. This applies to overrideDNs mostly,
* because those can contain either names or UUIDs
*/
}
return NULL;
}
return NULL;
}
"Cannot determine domain of %s\n",
goto done;
}
goto done;
}
goto done;
}
"Cannot get parent of %s\n",
goto done;
}
done:
return new_dn;
}
struct ldb_message *msg,
struct ldb_message *mod_msg,
struct sss_names_ctx *names,
const char *attrname)
{
return EOK;
}
return ENOMEM;
}
continue;
}
if (!ldb_dn_validate(attr_dn)) {
continue;
}
continue;
}
if (ret != LDB_SUCCESS) {
continue;
}
}
}
return EOK;
}
struct ldb_message *mod_msg)
{
};
continue;
}
if (ret != LDB_SUCCESS) {
return ret;
}
if (ret != LDB_SUCCESS) {
return ret;
}
}
return EOK;
}
struct ldb_context *ldb,
struct sss_names_ctx *names,
struct ldb_message *object,
bool qualify_dn,
const char *domain_attr,
unsigned domain_index,
const char *name_attrs[],
const char *dn_attrs[],
{
int ret;
const char *dom_name;
return ENOMEM;
}
"Cannot determine domain of %s\n",
return EINVAL;
}
if (name_attrs != NULL) {
for (size_t c = 0; name_attrs[c]; c++) {
"Cannot qualify %s of %s\n",
continue;
}
}
}
"Cannot qualify %s of %s\n",
}
}
}
}
/* Override objects can contain both qualified and non-qualified names.
* Need to use permissive modification here, otherwise we might attempt
* to store duplicate qualified names
*/
if (ret != LDB_SUCCESS) {
goto done;
}
if (qualify_dn) {
if (new_object_dn == NULL) {
goto done;
}
if (ret != LDB_SUCCESS) {
"Cannot rename %s to %s\n",
goto done;
}
}
done:
return ret;
}
struct ldb_context *ldb,
struct sss_names_ctx *names,
bool qualify_dn,
const char *domain_attr,
unsigned domain_index,
const char *filter,
const char *name_attrs[],
const char *dn_attrs[],
{
if (ret != LDB_SUCCESS) {
return;
}
return;
}
"Could not qualify object %s: %d\n",
continue;
}
}
}
struct ldb_context *ldb,
struct sss_names_ctx *names,
{
};
};
true, /* qualify dn */
NULL, /* no special domain attr, use DN */
2, /* DN's domain is third RDN from top */
}
struct ldb_context *ldb,
struct sss_names_ctx *names,
{
};
};
}
struct ldb_context *ldb,
struct sss_names_ctx *names,
{
};
};
/* Don't qualify RDN of override DN */
false,
/* Read domain from override DN */
2, /* Third RDN from top is domain */
}
struct ldb_context *ldb,
struct sss_names_ctx *names,
{
};
};
false, SYSDB_OVERRIDE_OBJECT_DN, 2,
}
struct ldb_context *ldb,
struct sss_names_ctx *names,
{
};
false, NULL, 3,
}
struct sysdb_dom_upgrade_ctx *upgrade_ctx,
const char **ver)
{
return EINVAL;
}
if (ret) {
return ret;
}
/* Disable memberof plugin during this update */
if (ret != 0) {
goto done;
}
goto done;
}
/* conversion done, update version number */
done:
"Cannot unset SSSD_UPGRADE_DB, SSSD might not work correctly\n");
}
return ret;
}
/*
* Example template for future upgrades.
* Copy and change version numbers as appropriate.
*/
#if 0
{
struct upgrade_ctx *ctx;
if (ret) {
return ret;
}
/* DO STUFF HERE (use ctx, as the local temporary memory context) */
/* conversion done, update version number */
done:
return ret;
}
#endif