sysdb.c revision 580374daba2ab2c6075a7d0de9512abff133e2e9
/*
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 "util/strtonum.h"
#include "db/sysdb_private.h"
#include <time.h>
const char *domain,
const char *subtree_name)
{
}
const char *domain, const char *object_name,
const char *subtree_name)
{
}
{
}
{
}
{
}
const char *domain)
{
}
{
return ENOMEM;
}
return EINVAL;
}
if (!*_name) {
return ENOMEM;
}
return EOK;
}
const char *domain)
{
}
{
}
{
}
{
struct ldb_message_element *e = NULL;
int i;
e = &(attrs->a[i]);
}
if (!e && alloc) {
if (!e) return ENOMEM;
attrs->a = e;
}
if (!e) {
return ENOENT;
}
*el = e;
return EOK;
}
struct ldb_message_element **el)
{
}
const char **string)
{
struct ldb_message_element *el;
int ret;
if (ret) {
return ret;
}
return ERANGE;
}
return EOK;
}
{
struct ldb_message_element *el;
int ret;
char *endptr;
if (ret) {
return ret;
}
return ERANGE;
}
errno = 0;
return EOK;
}
{
struct ldb_message_element *el;
int ret;
unsigned int u;
const char **a;
if (ret) {
return ret;
}
if (a == NULL) {
return ENOMEM;
}
for(u = 0; u < el->num_values; u++) {
if (a[u] == NULL) {
talloc_free(a);
return ENOMEM;
}
}
*string = a;
return EOK;
}
{
int ret;
return ret;
}
return ENOMEM;
}
el->num_values++;
return EOK;
}
{
struct ldb_val v;
}
{
if(value) {
}
}
{
int ret;
/* now steal and assign the string */
el->num_values++;
return EOK;
}
{
struct ldb_val v;
char *str;
int ret;
return ret;
}
{
struct ldb_val v;
char *str;
int ret;
return ret;
}
{
struct ldb_val v;
char *str;
int ret;
return ret;
}
const char *attr_name,
const char *domain,
const char **list)
{
int i, j, num;
char *member;
int ret;
if (ret) {
return ret;
}
if (!vals) {
return ENOMEM;
}
if (!member) {
continue;
}
j++;
}
el->num_values = j;
return EOK;
}
const char *attr_name,
const char *domain,
int num_values)
{
int i, j;
char *member;
int ret;
if (ret) {
return ret;
}
if (!vals) {
return ENOMEM;
}
if (!member) {
return ENOMEM;
}
j++;
}
el->num_values = j;
return EOK;
}
{
char *ret;
int l;
if (name[l] != '\0') {
struct ldb_val v;
char *tmp;
if (!tmp) {
return NULL;
}
if (!ret) {
return NULL;
}
return ret;
}
if (!ret) {
return NULL;
}
return ret;
}
{
}
{
}
/* TODO: make a more complete and precise mapping */
int sysdb_error_to_errno(int ldberr)
{
switch (ldberr) {
case LDB_SUCCESS:
return EOK;
case LDB_ERR_OPERATIONS_ERROR:
return EIO;
case LDB_ERR_NO_SUCH_OBJECT:
return ENOENT;
case LDB_ERR_BUSY:
return EBUSY;
return EEXIST;
default:
return EFAULT;
}
}
/* =Transactions========================================================== */
{
int ret;
if (ret != LDB_SUCCESS) {
}
return sysdb_error_to_errno(ret);
}
{
int ret;
if (ret != LDB_SUCCESS) {
}
return sysdb_error_to_errno(ret);
}
{
int ret;
if (ret != LDB_SUCCESS) {
}
return sysdb_error_to_errno(ret);
}
/* =Initialization======================================================== */
struct sss_domain_info *domain,
const char *db_path,
bool allow_upgrade,
{
char *ldb_file;
/* special case for the local domain */
} else {
}
if (!ldb_file) {
return ENOMEM;
}
return EOK;
}
/* 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
*/
struct ldb_context *ldb,
const char **ver)
{
struct ldb_message_element *el;
struct ldb_result *res;
struct ldb_message *msg;
const char *filter = "(&(memberUid=*)(objectclass=group))";
const char *mdn;
char *domain;
int ret, i, j;
if (!basedn) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
if (!el) {
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, 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;
}
done:
} else {
if (ret != LDB_SUCCESS) {
return EIO;
}
*ver = SYSDB_VERSION_0_2;
}
return ret;
}
struct sss_domain_info *domains,
const char *db_path)
{
struct ldb_context *ldb;
char *ldb_file;
struct sss_domain_info *dom;
struct ldb_message_element *el;
struct ldb_message *msg;
struct ldb_result *res;
bool do_02_upgrade = false;
bool ctx_trans = false;
int ret;
if (!tmp_ctx) {
return ENOMEM;
}
"local", "UPGRADE",
goto exit;
}
if (!ldb) {
goto exit;
}
if (ret != LDB_SUCCESS) {
goto exit;
}
#ifdef SYSDB_TEST
#endif
if (ret != LDB_SUCCESS) {
goto exit;
}
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;
}
/* 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 == */
/* 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 */
if (!ldb) {
goto exit;
}
if (ret != LDB_SUCCESS) {
goto exit;
}
if (ret != LDB_SUCCESS) {
goto exit;
}
/* open a transaction */
if (ret != LDB_SUCCESS) {
goto exit;
}
/* == Upgrade contents == */
int i;
/* skip local */
continue;
}
/* create new dom db */
goto done;
}
if (ret != LDB_SUCCESS) {
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;
}
if (!users_dn) {
goto done;
}
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) {
DEBUG(0, ("WARNING: Could not add entry %s,"
" to new ldb file! (%d [%s])\n",
}
if (ret != LDB_SUCCESS) {
DEBUG(0, ("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) {
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) {
goto exit;
}
done:
if (ctx_trans) {
if (ret != LDB_SUCCESS) {
}
}
if (ret != LDB_SUCCESS) {
}
}
exit:
return ret;
}
{
int ret;
struct ldb_message *msg;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* 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, 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;
}
done:
} else {
*ver = SYSDB_VERSION_0_4;
}
if (ret != LDB_SUCCESS) {
}
return ret;
}
{
int ret;
struct ldb_message *msg;
if (!tmp_ctx) {
return ENOMEM;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* 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, 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;
}
done:
} else {
*ver = SYSDB_VERSION_0_5;
}
if (ret != LDB_SUCCESS) {
}
return ret;
}
struct sss_domain_info *domain,
const char *db_path,
bool allow_upgrade,
{
const char *base_ldif;
struct ldb_message *msg;
struct ldb_message_element *el;
struct ldb_result *res;
int ret;
if (!ctx) {
return ENOMEM;
}
/* The local provider s the only true MPG,
* for the other domains, the provider actually unrolls MPGs */
}
return ret;
}
return EIO;
}
if (ret != LDB_SUCCESS) {
return EIO;
}
#ifdef SYSDB_TEST
#endif
if (ret != LDB_SUCCESS) {
return EIO;
}
if (!tmp_ctx) {
return ENOMEM;
}
if (!verdn) {
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
goto done;
}
if (el) {
goto done;
}
if (!version) {
goto done;
}
/* all fine, return */
goto done;
}
if (!allow_upgrade) {
DEBUG(0, ("Wrong DB version (got %s expected %s)\n",
version, SYSDB_VERSION));
goto done;
}
goto done;
}
}
goto done;
}
}
DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",
goto done;
}
/* cn=sysdb does not exists, means db is empty, populate */
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!\n",
goto done;
}
}
/* == create base domain object == */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* do a synchronous add */
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!\n",
goto done;
}
/* == create Users tree == */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* do a synchronous add */
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!\n",
goto done;
}
/* == create Groups tree == */
if (!msg) {
goto done;
}
goto done;
}
if (ret != LDB_SUCCESS) {
goto done;
}
/* do a synchronous add */
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!\n",
goto done;
}
done:
}
return ret;
}
struct confdb_ctx *cdb,
const char *alt_db_path,
bool allow_upgrade,
struct sysdb_ctx_list **_ctx_list)
{
struct sysdb_ctx_list *ctx_list;
int ret;
if (!ctx_list) {
return ENOMEM;
}
if (alt_db_path) {
} else {
}
return ENOMEM;
}
/* open a db for each backend */
return ret;
}
if (allow_upgrade) {
/* check if we have an old sssd.ldb to upgrade */
return ret;
}
}
struct sysdb_ctx *,
return ENOMEM;
}
allow_upgrade, &ctx);
return ret;
}
}
/* what? .. */
return ENOENT;
}
return EOK;
}
struct sss_domain_info *domain,
const char *db_path,
{
}
struct sss_domain_info *domain,
{
int i;
return EOK;
}
return EOK;
}
}
/* definitely not found */
return ENOENT;
}
{
struct ldb_message);
struct ldb_message);
}
const char *newname)
{
struct ldb_message_element *e = NULL;
int i;
const char *dummy;
e = &(attrs->a[i]);
}
return EEXIST;
}
}
if (e != NULL) {
return ENOMEM;
}
}
return EOK;
}
/* Search for all incidences of attr_name in a list of
* sysdb_attrs and add their value to a list
*
* TODO: Currently only works for single-valued
* attributes. Multi-valued attributes will return
* only the first entry
*/
struct sysdb_attrs **attrs,
int attr_count,
const char *attr_name,
char ***_list)
{
int attr_idx;
int i;
char **list;
char **tmp_list;
int list_idx;
/* Assume that every attrs entry contains the attr_name
* This may waste a little memory if some entries don't
* have the attribute, but it will save us the trouble
* of continuously resizing the array.
*/
if (!list) {
return ENOMEM;
}
list_idx = 0;
/* Loop through all entries in attrs */
/* Examine each attribute within the entry */
/* Attribute name matches the requested name
* Copy it to the output list
*/
list,
return ENOMEM;
}
list_idx++;
/* We only support single-valued attributes
* Break here and go on to the next entry
*/
break;
}
}
}
/* if list_idx < attr_count, do a realloc to
* reclaim unused memory
*/
if (list_idx < attr_count) {
if (!tmp_list) {
return ENOMEM;
}
}
return EOK;
}