wmi-1.3.16 from opsview.com

This commit is contained in:
Are Casilla
2019-02-16 00:16:52 +01:00
parent 163fdd3d1b
commit 17b3af2911
2146 changed files with 678824 additions and 0 deletions
+626
View File
@@ -0,0 +1,626 @@
/*
ldb database library
Copyright (C) Andrew Bartlett 2006
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ad2oLschema
*
* Description: utility to convert an AD schema into the format required by OpenLDAP
*
* Author: Andrew Tridgell
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "system/locale.h"
#include "ldb/tools/cmdline.h"
#include "ldb/tools/convert.h"
struct schema_conv {
int count;
int skipped;
int failures;
};
enum convert_target {
TARGET_OPENLDAP,
TARGET_FEDORA_DS
};
static void usage(void)
{
printf("Usage: ad2oLschema <options>\n");
printf("\nConvert AD-like LDIF to OpenLDAP schema format\n\n");
printf("Options:\n");
printf(" -I inputfile inputfile of mapped OIDs and skipped attributes/ObjectClasses");
printf(" -H url LDB or LDAP server to read schmea from\n");
printf(" -O outputfile outputfile otherwise STDOUT\n");
printf(" -o options pass options like modules to activate\n");
printf(" e.g: -o modules:timestamps\n");
printf("\n");
printf("Converts records from an AD-like LDIF schema into an openLdap formatted schema\n\n");
exit(1);
}
static int fetch_attrs_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
TALLOC_CTX *mem_ctx,
struct ldb_result **attrs_res)
{
TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
int ret;
const char *attrs[] = {
"lDAPDisplayName",
"isSingleValued",
"attributeID",
"attributeSyntax",
"description",
NULL
};
if (!local_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
}
/* Downlaod schema */
ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
"objectClass=attributeSchema",
attrs, attrs_res);
if (ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return LDB_ERR_OPERATIONS_ERROR;
}
return ret;
}
static const char *oc_attrs[] = {
"lDAPDisplayName",
"mayContain",
"mustContain",
"systemMayContain",
"systemMustContain",
"objectClassCategory",
"governsID",
"description",
"subClassOf",
NULL
};
static int fetch_oc_recursive(struct ldb_context *ldb, struct ldb_dn *schemadn,
TALLOC_CTX *mem_ctx,
struct ldb_result *search_from,
struct ldb_result *res_list)
{
int i;
int ret = 0;
for (i=0; i < search_from->count; i++) {
struct ldb_result *res;
const char *name = ldb_msg_find_attr_as_string(search_from->msgs[i],
"lDAPDisplayname", NULL);
ret = ldb_search_exp_fmt(ldb, mem_ctx, &res,
schemadn, LDB_SCOPE_SUBTREE, oc_attrs,
"(&(&(objectClass=classSchema)(subClassOf=%s))(!(lDAPDisplayName=%s)))",
name, name);
if (ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return ret;
}
res_list->msgs = talloc_realloc(res_list, res_list->msgs,
struct ldb_message *, res_list->count + 2);
if (!res_list->msgs) {
return LDB_ERR_OPERATIONS_ERROR;
}
res_list->msgs[res_list->count] = talloc_move(res_list,
&search_from->msgs[i]);
res_list->count++;
res_list->msgs[res_list->count] = NULL;
if (res->count > 0) {
ret = fetch_oc_recursive(ldb, schemadn, mem_ctx, res, res_list);
}
if (ret != LDB_SUCCESS) {
return ret;
}
}
return ret;
}
static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
TALLOC_CTX *mem_ctx,
struct ldb_result **objectclasses_res)
{
TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
struct ldb_result *top_res, *ret_res;
int ret;
if (!local_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
}
/* Downlaod 'top' */
ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
"(&(objectClass=classSchema)(lDAPDisplayName=top))",
oc_attrs, &top_res);
if (ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return LDB_ERR_OPERATIONS_ERROR;
}
talloc_steal(local_ctx, top_res);
if (top_res->count != 1) {
return LDB_ERR_OPERATIONS_ERROR;
}
ret_res = talloc_zero(local_ctx, struct ldb_result);
if (!ret_res) {
return LDB_ERR_OPERATIONS_ERROR;
}
ret = fetch_oc_recursive(ldb, schemadn, local_ctx, top_res, ret_res);
if (ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return LDB_ERR_OPERATIONS_ERROR;
}
*objectclasses_res = talloc_move(mem_ctx, &ret_res);
return ret;
}
static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
{
const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
struct ldb_dn *schemadn;
struct ldb_dn *basedn = ldb_dn_new(mem_ctx, ldb, NULL);
struct ldb_result *rootdse_res;
int ldb_ret;
if (!basedn) {
return NULL;
}
/* Search for rootdse */
ldb_ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, NULL, rootdse_attrs, &rootdse_res);
if (ldb_ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return NULL;
}
talloc_steal(mem_ctx, rootdse_res);
if (rootdse_res->count != 1) {
printf("Failed to find rootDSE");
return NULL;
}
/* Locate schema */
schemadn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
if (!schemadn) {
return NULL;
}
talloc_free(rootdse_res);
return schemadn;
}
#define IF_NULL_FAIL_RET(x) do { \
if (!x) { \
ret.failures++; \
return ret; \
} \
} while (0)
static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_target target, FILE *in, FILE *out)
{
/* Read list of attributes to skip, OIDs to map */
TALLOC_CTX *mem_ctx = talloc_new(ldb);
char *line;
const char **attrs_skip = NULL;
int num_skip = 0;
struct oid_map {
char *old_oid;
char *new_oid;
} *oid_map = NULL;
int num_maps = 0;
struct ldb_result *attrs_res, *objectclasses_res;
struct ldb_dn *schemadn;
struct schema_conv ret;
int ldb_ret, i;
ret.count = 0;
ret.skipped = 0;
ret.failures = 0;
while ((line = afdgets(fileno(in), mem_ctx, 0))) {
/* Blank Line */
if (line[0] == '\0') {
continue;
}
/* Comment */
if (line[0] == '#') {
continue;
}
if (isdigit(line[0])) {
char *p = strchr(line, ':');
IF_NULL_FAIL_RET(p);
if (!p) {
ret.failures = 1;
return ret;
}
p[0] = '\0';
p++;
oid_map = talloc_realloc(mem_ctx, oid_map, struct oid_map, num_maps + 2);
trim_string(line, " ", " ");
oid_map[num_maps].old_oid = talloc_move(oid_map, &line);
trim_string(p, " ", " ");
oid_map[num_maps].new_oid = p;
num_maps++;
oid_map[num_maps].old_oid = NULL;
} else {
attrs_skip = talloc_realloc(mem_ctx, attrs_skip, const char *, num_skip + 2);
trim_string(line, " ", " ");
attrs_skip[num_skip] = talloc_move(attrs_skip, &line);
num_skip++;
attrs_skip[num_skip] = NULL;
}
}
schemadn = find_schema_dn(ldb, mem_ctx);
if (!schemadn) {
printf("Failed to find schema DN: %s\n", ldb_errstring(ldb));
ret.failures = 1;
return ret;
}
ldb_ret = fetch_attrs_schema(ldb, schemadn, mem_ctx, &attrs_res);
if (ldb_ret != LDB_SUCCESS) {
printf("Failed to fetch attribute schema: %s\n", ldb_errstring(ldb));
ret.failures = 1;
return ret;
}
switch (target) {
case TARGET_OPENLDAP:
break;
case TARGET_FEDORA_DS:
fprintf(out, "dn: cn=schema\n");
break;
}
for (i=0; i < attrs_res->count; i++) {
struct ldb_message *msg = attrs_res->msgs[i];
const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL);
const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL);
const char *oid = ldb_msg_find_attr_as_string(msg, "attributeID", NULL);
const char *syntax = ldb_msg_find_attr_as_string(msg, "attributeSyntax", NULL);
BOOL single_value = ldb_msg_find_attr_as_bool(msg, "isSingleValued", False);
const struct syntax_map *map = find_syntax_map_by_ad_oid(syntax);
char *schema_entry = NULL;
int j;
/* We have been asked to skip some attributes/objectClasses */
if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
ret.skipped++;
continue;
}
/* We might have been asked to remap this oid, due to a conflict */
for (j=0; oid && oid_map[j].old_oid; j++) {
if (strcmp(oid, oid_map[j].old_oid) == 0) {
oid = oid_map[j].new_oid;
break;
}
}
switch (target) {
case TARGET_OPENLDAP:
schema_entry = talloc_asprintf(mem_ctx,
"attributetype (\n"
" %s\n", oid);
break;
case TARGET_FEDORA_DS:
schema_entry = talloc_asprintf(mem_ctx,
"attributeTypes: (\n"
" %s\n", oid);
break;
}
IF_NULL_FAIL_RET(schema_entry);
schema_entry = talloc_asprintf_append(schema_entry,
" NAME '%s'\n", name);
IF_NULL_FAIL_RET(schema_entry);
if (description) {
schema_entry = talloc_asprintf_append(schema_entry,
" DESC %s\n", description);
IF_NULL_FAIL_RET(schema_entry);
}
if (map) {
const char *syntax_oid;
if (map->equality) {
schema_entry = talloc_asprintf_append(schema_entry,
" EQUALITY %s\n", map->equality);
IF_NULL_FAIL_RET(schema_entry);
}
if (map->substring) {
schema_entry = talloc_asprintf_append(schema_entry,
" SUBSTR %s\n", map->substring);
IF_NULL_FAIL_RET(schema_entry);
}
syntax_oid = map->Standard_OID;
/* We might have been asked to remap this oid,
* due to a conflict, or lack of
* implementation */
for (j=0; syntax_oid && oid_map[j].old_oid; j++) {
if (strcmp(syntax_oid, oid_map[j].old_oid) == 0) {
syntax_oid = oid_map[j].new_oid;
break;
}
}
schema_entry = talloc_asprintf_append(schema_entry,
" SYNTAX %s\n", syntax_oid);
IF_NULL_FAIL_RET(schema_entry);
}
if (single_value) {
schema_entry = talloc_asprintf_append(schema_entry,
" SINGLE-VALUE\n");
IF_NULL_FAIL_RET(schema_entry);
}
schema_entry = talloc_asprintf_append(schema_entry,
" )");
switch (target) {
case TARGET_OPENLDAP:
fprintf(out, "%s\n\n", schema_entry);
break;
case TARGET_FEDORA_DS:
fprintf(out, "%s\n", schema_entry);
break;
}
ret.count++;
}
ldb_ret = fetch_objectclass_schema(ldb, schemadn, mem_ctx, &objectclasses_res);
if (ldb_ret != LDB_SUCCESS) {
printf("Failed to fetch objectClass schema elements: %s\n", ldb_errstring(ldb));
ret.failures = 1;
return ret;
}
for (i=0; i < objectclasses_res->count; i++) {
struct ldb_message *msg = objectclasses_res->msgs[i];
const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL);
const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL);
const char *oid = ldb_msg_find_attr_as_string(msg, "governsID", NULL);
const char *subClassOf = ldb_msg_find_attr_as_string(msg, "subClassOf", NULL);
int objectClassCategory = ldb_msg_find_attr_as_int(msg, "objectClassCategory", 0);
struct ldb_message_element *must = ldb_msg_find_element(msg, "mustContain");
struct ldb_message_element *sys_must = ldb_msg_find_element(msg, "systemMustContain");
struct ldb_message_element *may = ldb_msg_find_element(msg, "mayContain");
struct ldb_message_element *sys_may = ldb_msg_find_element(msg, "systemMayContain");
char *schema_entry = NULL;
int j;
/* We have been asked to skip some attributes/objectClasses */
if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
ret.skipped++;
continue;
}
/* We might have been asked to remap this oid, due to a conflict */
for (j=0; oid_map[j].old_oid; j++) {
if (strcmp(oid, oid_map[j].old_oid) == 0) {
oid = oid_map[j].new_oid;
break;
}
}
switch (target) {
case TARGET_OPENLDAP:
schema_entry = talloc_asprintf(mem_ctx,
"objectclass (\n"
" %s\n", oid);
break;
case TARGET_FEDORA_DS:
schema_entry = talloc_asprintf(mem_ctx,
"objectClasses: (\n"
" %s\n", oid);
break;
}
IF_NULL_FAIL_RET(schema_entry);
if (!schema_entry) {
ret.failures++;
break;
}
schema_entry = talloc_asprintf_append(schema_entry,
" NAME '%s'\n", name);
IF_NULL_FAIL_RET(schema_entry);
if (!schema_entry) return ret;
if (description) {
schema_entry = talloc_asprintf_append(schema_entry,
" DESC %s\n", description);
IF_NULL_FAIL_RET(schema_entry);
}
if (subClassOf) {
schema_entry = talloc_asprintf_append(schema_entry,
" SUP %s\n", subClassOf);
IF_NULL_FAIL_RET(schema_entry);
}
switch (objectClassCategory) {
case 1:
schema_entry = talloc_asprintf_append(schema_entry,
" STRUCTURAL\n");
IF_NULL_FAIL_RET(schema_entry);
break;
case 2:
schema_entry = talloc_asprintf_append(schema_entry,
" ABSTRACT\n");
IF_NULL_FAIL_RET(schema_entry);
break;
case 3:
schema_entry = talloc_asprintf_append(schema_entry,
" AUXILIARY\n");
IF_NULL_FAIL_RET(schema_entry);
break;
}
#define APPEND_ATTRS(attributes) \
do { \
int k; \
for (k=0; attributes && k < attributes->num_values; k++) { \
schema_entry = talloc_asprintf_append(schema_entry, \
" %s", \
(const char *)attributes->values[k].data); \
IF_NULL_FAIL_RET(schema_entry); \
if (k != (attributes->num_values - 1)) { \
schema_entry = talloc_asprintf_append(schema_entry, \
" $"); \
IF_NULL_FAIL_RET(schema_entry); \
if (target == TARGET_OPENLDAP && ((k+1)%5 == 0)) { \
schema_entry = talloc_asprintf_append(schema_entry, \
"\n "); \
IF_NULL_FAIL_RET(schema_entry); \
} \
} \
} \
} while (0)
if (must || sys_must) {
schema_entry = talloc_asprintf_append(schema_entry,
" MUST (");
IF_NULL_FAIL_RET(schema_entry);
APPEND_ATTRS(must);
if (must && sys_must) {
schema_entry = talloc_asprintf_append(schema_entry, \
" $"); \
}
APPEND_ATTRS(sys_must);
schema_entry = talloc_asprintf_append(schema_entry,
" )\n");
IF_NULL_FAIL_RET(schema_entry);
}
if (may || sys_may) {
schema_entry = talloc_asprintf_append(schema_entry,
" MAY (");
IF_NULL_FAIL_RET(schema_entry);
APPEND_ATTRS(may);
if (may && sys_may) {
schema_entry = talloc_asprintf_append(schema_entry, \
" $"); \
}
APPEND_ATTRS(sys_may);
schema_entry = talloc_asprintf_append(schema_entry,
" )\n");
IF_NULL_FAIL_RET(schema_entry);
}
schema_entry = talloc_asprintf_append(schema_entry,
" )");
switch (target) {
case TARGET_OPENLDAP:
fprintf(out, "%s\n\n", schema_entry);
break;
case TARGET_FEDORA_DS:
fprintf(out, "%s\n", schema_entry);
break;
}
ret.count++;
}
return ret;
}
int main(int argc, const char **argv)
{
TALLOC_CTX *ctx;
struct ldb_cmdline *options;
FILE *in = stdin;
FILE *out = stdout;
struct ldb_context *ldb;
struct schema_conv ret;
const char *target_str;
enum convert_target target;
ldb_global_init();
ctx = talloc_new(NULL);
ldb = ldb_init(ctx);
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (options->input) {
in = fopen(options->input, "r");
if (!in) {
perror(options->input);
exit(1);
}
}
if (options->output) {
out = fopen(options->output, "w");
if (!out) {
perror(options->output);
exit(1);
}
}
target_str = lp_parm_string(-1, "convert", "target");
if (!target_str || strcasecmp(target_str, "openldap") == 0) {
target = TARGET_OPENLDAP;
} else if (strcasecmp(target_str, "fedora-ds") == 0) {
target = TARGET_FEDORA_DS;
} else {
printf("Unsupported target: %s\n", target_str);
exit(1);
}
ret = process_convert(ldb, target, in, out);
fclose(in);
fclose(out);
printf("Converted %d records (skipped %d) with %d failures\n", ret.count, ret.skipped, ret.failures);
return 0;
}
+755
View File
@@ -0,0 +1,755 @@
/*
ldb database library - command line handling for ldb tools
Copyright (C) Andrew Tridgell 2005
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
#if (_SAMBA_BUILD_ >= 4)
#include "lib/cmdline/popt_common.h"
#include "lib/ldb/samba/ldif_handlers.h"
#include "auth/gensec/gensec.h"
#include "auth/auth.h"
#include "db_wrap.h"
#endif
/*
process command line options
*/
struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv,
void (*usage)(void))
{
static struct ldb_cmdline options; /* needs to be static for older compilers */
struct ldb_cmdline *ret=NULL;
poptContext pc;
#if (_SAMBA_BUILD_ >= 4)
int r;
#endif
int num_options = 0;
int opt;
int flags = 0;
struct poptOption popt_options[] = {
POPT_AUTOHELP
{ "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" },
{ "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" },
{ "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" },
{ "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" },
{ "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL },
{ "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL },
{ "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL },
{ "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL },
{ "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL },
{ "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL },
{ "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL },
{ "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL },
{ "sasl-mechanism", 0, POPT_ARG_STRING, &options.sasl_mechanism, 0, "choose SASL mechanism", "MECHANISM" },
{ "input", 'I', POPT_ARG_STRING, &options.input, 0, "Input File", "Input" },
{ "output", 'O', POPT_ARG_STRING, &options.output, 0, "Output File", "Output" },
{ NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" },
{ "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL },
#if (_SAMBA_BUILD_ >= 4)
POPT_COMMON_SAMBA
POPT_COMMON_CREDENTIALS
POPT_COMMON_VERSION
#endif
{ NULL }
};
ldb_global_init();
#if (_SAMBA_BUILD_ >= 4)
r = ldb_register_samba_handlers(ldb);
if (r != 0) {
goto failed;
}
#endif
ret = talloc_zero(ldb, struct ldb_cmdline);
if (ret == NULL) {
ldb_oom(ldb);
goto failed;
}
options = *ret;
/* pull in URL */
options.url = getenv("LDB_URL");
/* and editor (used by ldbedit) */
options.editor = getenv("VISUAL");
if (!options.editor) {
options.editor = getenv("EDITOR");
}
if (!options.editor) {
options.editor = "vi";
}
options.scope = LDB_SCOPE_DEFAULT;
pc = poptGetContext(argv[0], argc, argv, popt_options,
POPT_CONTEXT_KEEP_FIRST);
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case 's': {
const char *arg = poptGetOptArg(pc);
if (strcmp(arg, "base") == 0) {
options.scope = LDB_SCOPE_BASE;
} else if (strcmp(arg, "sub") == 0) {
options.scope = LDB_SCOPE_SUBTREE;
} else if (strcmp(arg, "one") == 0) {
options.scope = LDB_SCOPE_ONELEVEL;
} else {
fprintf(stderr, "Invalid scope '%s'\n", arg);
goto failed;
}
break;
}
case 'v':
options.verbose++;
break;
case 'o':
options.options = talloc_realloc(ret, options.options,
const char *, num_options+3);
if (options.options == NULL) {
ldb_oom(ldb);
goto failed;
}
options.options[num_options] = poptGetOptArg(pc);
options.options[num_options+1] = NULL;
num_options++;
break;
case 'c': {
const char *cs = poptGetOptArg(pc);
const char *p, *q;
int cc;
for (p = cs, cc = 1; (q = strchr(p, ',')); cc++, p = q + 1) ;
options.controls = talloc_array(ret, char *, cc + 1);
if (options.controls == NULL) {
ldb_oom(ldb);
goto failed;
}
for (p = cs, cc = 0; p != NULL; cc++) {
const char *t;
t = strchr(p, ',');
if (t == NULL) {
options.controls[cc] = talloc_strdup(options.controls, p);
p = NULL;
} else {
options.controls[cc] = talloc_strndup(options.controls, p, t-p);
p = t + 1;
}
}
options.controls[cc] = NULL;
break;
}
default:
fprintf(stderr, "Invalid option %s: %s\n",
poptBadOption(pc, 0), poptStrerror(opt));
if (usage) usage();
goto failed;
}
}
/* setup the remaining options for the main program to use */
options.argv = poptGetArgs(pc);
if (options.argv) {
options.argv++;
while (options.argv[options.argc]) options.argc++;
}
*ret = options;
/* all utils need some option */
if (ret->url == NULL) {
fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n");
if (usage) usage();
goto failed;
}
if (strcmp(ret->url, "NONE") == 0) {
return ret;
}
if (options.nosync) {
flags |= LDB_FLG_NOSYNC;
}
#if (_SAMBA_BUILD_ >= 4)
/* Must be after we have processed command line options */
gensec_init();
if (ldb_set_opaque(ldb, "sessionInfo", system_session(ldb))) {
goto failed;
}
if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) {
goto failed;
}
ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
#endif
/* now connect to the ldb */
if (ldb_connect(ldb, ret->url, flags, ret->options) != 0) {
fprintf(stderr, "Failed to connect to %s - %s\n",
ret->url, ldb_errstring(ldb));
goto failed;
}
return ret;
failed:
talloc_free(ret);
exit(1);
return NULL;
}
struct ldb_control **parse_controls(void *mem_ctx, char **control_strings)
{
int i;
struct ldb_control **ctrl;
if (control_strings == NULL || control_strings[0] == NULL)
return NULL;
for (i = 0; control_strings[i]; i++);
ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
for (i = 0; control_strings[i]; i++) {
if (strncmp(control_strings[i], "vlv:", 4) == 0) {
struct ldb_vlv_req_control *control;
const char *p;
char attr[1024];
char ctxid[1024];
int crit, bc, ac, os, cc, ret;
attr[0] = '\0';
ctxid[0] = '\0';
p = &(control_strings[i][4]);
ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
if (ret < 5) {
ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
}
if ((ret < 4) || (crit < 0) || (crit > 1)) {
fprintf(stderr, "invalid server_sort control syntax\n");
fprintf(stderr, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
fprintf(stderr, " note: b = boolean, n = number, s = string, o = b64 binary blob\n");
return NULL;
}
if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
fprintf(stderr, "talloc failed\n");
return NULL;
}
ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
ctrl[i]->critical = crit;
if (!(control = talloc(ctrl[i],
struct ldb_vlv_req_control))) {
fprintf(stderr, "talloc failed\n");
return NULL;
}
control->beforeCount = bc;
control->afterCount = ac;
if (attr[0]) {
control->type = 1;
control->match.gtOrEq.value = talloc_strdup(control, attr);
control->match.gtOrEq.value_len = strlen(attr);
} else {
control->type = 0;
control->match.byOffset.offset = os;
control->match.byOffset.contentCount = cc;
}
if (ctxid[0]) {
control->ctxid_len = ldb_base64_decode(ctxid);
control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
} else {
control->ctxid_len = 0;
control->contextId = NULL;
}
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
struct ldb_dirsync_control *control;
const char *p;
char cookie[1024];
int crit, flags, max_attrs, ret;
cookie[0] = '\0';
p = &(control_strings[i][8]);
ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
fprintf(stderr, "invalid dirsync control syntax\n");
fprintf(stderr, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
fprintf(stderr, " note: b = boolean, n = number, o = b64 binary blob\n");
return NULL;
}
/* w2k3 seems to ignore the parameter,
* but w2k sends a wrong cookie when this value is to small
* this would cause looping forever, while getting
* the same data and same cookie forever
*/
if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
ctrl[i]->critical = crit;
control = talloc(ctrl[i], struct ldb_dirsync_control);
control->flags = flags;
control->max_attributes = max_attrs;
if (*cookie) {
control->cookie_len = ldb_base64_decode(cookie);
control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
} else {
control->cookie = NULL;
control->cookie_len = 0;
}
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "asq:", 4) == 0) {
struct ldb_asq_control *control;
const char *p;
char attr[256];
int crit, ret;
attr[0] = '\0';
p = &(control_strings[i][4]);
ret = sscanf(p, "%d:%255[^$]", &crit, attr);
if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
fprintf(stderr, "invalid asq control syntax\n");
fprintf(stderr, " syntax: crit(b):attr(s)\n");
fprintf(stderr, " note: b = boolean, s = string\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
ctrl[i]->critical = crit;
control = talloc(ctrl[i], struct ldb_asq_control);
control->request = 1;
control->source_attribute = talloc_strdup(control, attr);
control->src_attr_len = strlen(attr);
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
struct ldb_extended_dn_control *control;
const char *p;
int crit, type, ret;
p = &(control_strings[i][12]);
ret = sscanf(p, "%d:%d", &crit, &type);
if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
fprintf(stderr, "invalid extended_dn control syntax\n");
fprintf(stderr, " syntax: crit(b):type(b)\n");
fprintf(stderr, " note: b = boolean\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
ctrl[i]->critical = crit;
control = talloc(ctrl[i], struct ldb_extended_dn_control);
control->type = type;
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
struct ldb_sd_flags_control *control;
const char *p;
int crit, ret;
unsigned secinfo_flags;
p = &(control_strings[i][9]);
ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
fprintf(stderr, "invalid sd_flags control syntax\n");
fprintf(stderr, " syntax: crit(b):secinfo_flags(n)\n");
fprintf(stderr, " note: b = boolean, n = number\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
ctrl[i]->critical = crit;
control = talloc(ctrl[i], struct ldb_sd_flags_control);
control->secinfo_flags = secinfo_flags;
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "search_options:", 15) == 0) {
struct ldb_search_options_control *control;
const char *p;
int crit, ret;
unsigned search_options;
p = &(control_strings[i][15]);
ret = sscanf(p, "%d:%u", &crit, &search_options);
if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
fprintf(stderr, "invalid search_options control syntax\n");
fprintf(stderr, " syntax: crit(b):search_options(n)\n");
fprintf(stderr, " note: b = boolean, n = number\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
ctrl[i]->critical = crit;
control = talloc(ctrl[i], struct ldb_search_options_control);
control->search_options = search_options;
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
const char *p;
int crit, ret;
p = &(control_strings[i][13]);
ret = sscanf(p, "%d", &crit);
if ((ret != 1) || (crit < 0) || (crit > 1)) {
fprintf(stderr, "invalid domain_scope control syntax\n");
fprintf(stderr, " syntax: crit(b)\n");
fprintf(stderr, " note: b = boolean\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
ctrl[i]->critical = crit;
ctrl[i]->data = NULL;
continue;
}
if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
struct ldb_paged_control *control;
const char *p;
int crit, size, ret;
p = &(control_strings[i][14]);
ret = sscanf(p, "%d:%d", &crit, &size);
if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
fprintf(stderr, "invalid paged_results control syntax\n");
fprintf(stderr, " syntax: crit(b):size(n)\n");
fprintf(stderr, " note: b = boolean, n = number\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
ctrl[i]->critical = crit;
control = talloc(ctrl[i], struct ldb_paged_control);
control->size = size;
control->cookie = NULL;
control->cookie_len = 0;
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
struct ldb_server_sort_control **control;
const char *p;
char attr[256];
char rule[128];
int crit, rev, ret;
attr[0] = '\0';
rule[0] = '\0';
p = &(control_strings[i][12]);
ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
fprintf(stderr, "invalid server_sort control syntax\n");
fprintf(stderr, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
fprintf(stderr, " note: b = boolean, s = string\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
ctrl[i]->critical = crit;
control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2);
control[0] = talloc(control, struct ldb_server_sort_control);
control[0]->attributeName = talloc_strdup(control, attr);
if (rule[0])
control[0]->orderingRule = talloc_strdup(control, rule);
else
control[0]->orderingRule = NULL;
control[0]->reverse = rev;
control[1] = NULL;
ctrl[i]->data = control;
continue;
}
if (strncmp(control_strings[i], "notification:", 13) == 0) {
const char *p;
int crit, ret;
p = &(control_strings[i][13]);
ret = sscanf(p, "%d", &crit);
if ((ret != 1) || (crit < 0) || (crit > 1)) {
fprintf(stderr, "invalid notification control syntax\n");
fprintf(stderr, " syntax: crit(b)\n");
fprintf(stderr, " note: b = boolean\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
ctrl[i]->critical = crit;
ctrl[i]->data = NULL;
continue;
}
if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
const char *p;
int crit, ret;
p = &(control_strings[i][13]);
ret = sscanf(p, "%d", &crit);
if ((ret != 1) || (crit < 0) || (crit > 1)) {
fprintf(stderr, "invalid show_deleted control syntax\n");
fprintf(stderr, " syntax: crit(b)\n");
fprintf(stderr, " note: b = boolean\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
ctrl[i]->critical = crit;
ctrl[i]->data = NULL;
continue;
}
if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
const char *p;
int crit, ret;
p = &(control_strings[i][18]);
ret = sscanf(p, "%d", &crit);
if ((ret != 1) || (crit < 0) || (crit > 1)) {
fprintf(stderr, "invalid permissive_modify control syntax\n");
fprintf(stderr, " syntax: crit(b)\n");
fprintf(stderr, " note: b = boolean\n");
return NULL;
}
ctrl[i] = talloc(ctrl, struct ldb_control);
ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
ctrl[i]->critical = crit;
ctrl[i]->data = NULL;
continue;
}
/* no controls matched, throw an error */
fprintf(stderr, "Invalid control name: '%s'\n", control_strings[i]);
return NULL;
}
ctrl[i] = NULL;
return ctrl;
}
/* this function check controls reply and determines if more
* processing is needed setting up the request controls correctly
*
* returns:
* -1 error
* 0 all ok
* 1 all ok, more processing required
*/
int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request)
{
int i, j;
int ret = 0;
if (reply == NULL || request == NULL) return -1;
for (i = 0; reply[i]; i++) {
if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) {
struct ldb_vlv_resp_control *rep_control;
rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control);
/* check we have a matching control in the request */
for (j = 0; request[j]; j++) {
if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0)
break;
}
if (! request[j]) {
fprintf(stderr, "Warning VLV reply received but no request have been made\n");
continue;
}
/* check the result */
if (rep_control->vlv_result != 0) {
fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result);
} else {
fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount);
}
continue;
}
if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) {
struct ldb_asq_control *rep_control;
rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control);
/* check the result */
if (rep_control->result != 0) {
fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result);
}
continue;
}
if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) {
struct ldb_paged_control *rep_control, *req_control;
rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control);
if (rep_control->cookie_len == 0) /* we are done */
break;
/* more processing required */
/* let's fill in the request control with the new cookie */
for (j = 0; request[j]; j++) {
if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0)
break;
}
/* if there's a reply control we must find a request
* control matching it */
if (! request[j]) return -1;
req_control = talloc_get_type(request[j]->data, struct ldb_paged_control);
if (req_control->cookie)
talloc_free(req_control->cookie);
req_control->cookie = (char *)talloc_memdup(
req_control, rep_control->cookie,
rep_control->cookie_len);
req_control->cookie_len = rep_control->cookie_len;
ret = 1;
continue;
}
if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) {
struct ldb_sort_resp_control *rep_control;
rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control);
/* check we have a matching control in the request */
for (j = 0; request[j]; j++) {
if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0)
break;
}
if (! request[j]) {
fprintf(stderr, "Warning Server Sort reply received but no request found\n");
continue;
}
/* check the result */
if (rep_control->result != 0) {
fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result);
}
continue;
}
if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) {
struct ldb_dirsync_control *rep_control, *req_control;
char *cookie;
rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control);
if (rep_control->cookie_len == 0) /* we are done */
break;
/* more processing required */
/* let's fill in the request control with the new cookie */
for (j = 0; request[j]; j++) {
if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0)
break;
}
/* if there's a reply control we must find a request
* control matching it */
if (! request[j]) return -1;
req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control);
if (req_control->cookie)
talloc_free(req_control->cookie);
req_control->cookie = (char *)talloc_memdup(
req_control, rep_control->cookie,
rep_control->cookie_len);
req_control->cookie_len = rep_control->cookie_len;
cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len);
printf("# DIRSYNC cookie returned was:\n# %s\n", cookie);
continue;
}
/* no controls matched, throw a warning */
fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid);
}
return ret;
}
+54
View File
@@ -0,0 +1,54 @@
/*
ldb database library - command line handling for ldb tools
Copyright (C) Andrew Tridgell 2005
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <popt.h>
struct ldb_cmdline {
const char *url;
enum ldb_scope scope;
const char *basedn;
int interactive;
int sorted;
const char *editor;
int verbose;
int recursive;
int all_records;
int nosync;
const char **options;
int argc;
const char **argv;
int num_records;
int num_searches;
const char *sasl_mechanism;
const char *input;
const char *output;
char **controls;
};
struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv,
void (*usage)(void));
struct ldb_control **parse_controls(void *mem_ctx, char **control_strings);
int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request);
+166
View File
@@ -0,0 +1,166 @@
/*
ldb database library
Copyright (C) Simo Sorce 2005
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "convert.h"
#include "includes.h"
#include "ldb/include/includes.h"
/* Shared map for converting syntax between formats */
static const struct syntax_map syntax_map[] = {
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.12",
.AD_OID = "2.5.5.1",
.equality = "distinguishedNameMatch",
.comment = "Object(DS-DN) == a DN"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.38",
.AD_OID = "2.5.5.2",
.equality = "objectIdentifierMatch",
.comment = "OID String"
},
{
.Standard_OID = "1.2.840.113556.1.4.905",
.AD_OID = "2.5.5.4",
.equality = "caseIgnoreMatch",
.substring = "caseIgnoreSubstringsMatch",
.comment = "Case Insensitive String"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.26",
.AD_OID = "2.5.5.5",
.equality = "caseExactIA5Match",
.comment = "Printable String"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.36",
.AD_OID = "2.5.5.6",
.equality = "numericStringMatch",
.substring = "numericStringSubstringsMatch",
.comment = "Numeric String"
},
{
.Standard_OID = "1.2.840.113556.1.4.903",
.AD_OID = "2.5.5.7",
.equality = "distinguishedNameMatch",
.comment = "OctetString: Binary+DN"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.7",
.AD_OID = "2.5.5.8",
.equality = "booleanMatch",
.comment = "Boolean"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.27",
.AD_OID = "2.5.5.9",
.equality = "integerMatch",
.comment = "Integer"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.40",
.AD_OID = "2.5.5.10",
.equality = "octetStringMatch",
.comment = "Octet String"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.24",
.AD_OID = "2.5.5.11",
.equality = "generalizedTimeMatch",
.comment = "Generalized Time"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.53",
.AD_OID = "2.5.5.11",
.equality = "generalizedTimeMatch",
.comment = "UTC Time"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.15",
.AD_OID = "2.5.5.12",
.equality = "caseIgnoreMatch",
.substring = "caseIgnoreSubstringsMatch",
.comment = "Directory String"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.43",
.AD_OID = "2.5.5.13",
.comment = "Presentation Address"
},
{
.Standard_OID = "Not Found Yet",
.AD_OID = "2.5.5.14",
.equality = "distinguishedNameMatch",
.comment = "OctetString: String+DN"
},
{
.Standard_OID = "1.2.840.113556.1.4.907",
.AD_OID = "2.5.5.15",
.equality = "octetStringMatch",
.comment = "NT Security Descriptor"
},
{
.Standard_OID = "1.2.840.113556.1.4.906",
.AD_OID = "2.5.5.16",
.equality = "integerMatch",
.comment = "Large Integer"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.40",
.AD_OID = "2.5.5.17",
.equality = "octetStringMatch",
.comment = "Octet String - Security Identifier (SID)"
},
{
.Standard_OID = "1.3.6.1.4.1.1466.115.121.1.26",
.AD_OID = "2.5.5.5",
.equality = "caseExactIA5Match",
.comment = "IA5 String"
},
{ .Standard_OID = NULL
}
};
const struct syntax_map *find_syntax_map_by_ad_oid(const char *ad_oid)
{
int i;
for (i=0; syntax_map[i].Standard_OID; i++) {
if (strcasecmp(ad_oid, syntax_map[i].AD_OID) == 0) {
return &syntax_map[i];
}
}
return NULL;
}
const struct syntax_map *find_syntax_map_by_standard_oid(const char *standard_oid)
{
int i;
for (i=0; syntax_map[i].Standard_OID; i++) {
if (strcasecmp(standard_oid, syntax_map[i].Standard_OID) == 0) {
return &syntax_map[i];
}
}
return NULL;
}
+10
View File
@@ -0,0 +1,10 @@
struct syntax_map {
const char *Standard_OID;
const char *AD_OID;
const char *equality;
const char *substring;
const char *comment;
};
const struct syntax_map *find_syntax_map_by_ad_oid(const char *ad_oid);
const struct syntax_map *find_syntax_map_by_standard_oid(const char *standard_oid);
+120
View File
@@ -0,0 +1,120 @@
/*
ldb database library
Copyright (C) Andrew Tridgell 2004
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ldbadd
*
* Description: utility to add records - modelled on ldapadd
*
* Author: Andrew Tridgell
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
static int failures;
static void usage(void)
{
printf("Usage: ldbadd <options> <ldif...>\n");
printf("Options:\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
printf(" -o options pass options like modules to activate\n");
printf(" e.g: -o modules:timestamps\n");
printf("\n");
printf("Adds records to a ldb, reading ldif the specified list of files\n\n");
exit(1);
}
/*
add records from an opened file
*/
static int process_file(struct ldb_context *ldb, FILE *f, int *count)
{
struct ldb_ldif *ldif;
int ret = LDB_SUCCESS;
while ((ldif = ldb_ldif_read_file(ldb, f))) {
if (ldif->changetype != LDB_CHANGETYPE_ADD &&
ldif->changetype != LDB_CHANGETYPE_NONE) {
fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n");
break;
}
ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg);
ret = ldb_add(ldb, ldif->msg);
if (ret != LDB_SUCCESS) {
fprintf(stderr, "ERR: \"%s\" on DN %s\n",
ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn));
failures++;
} else {
(*count)++;
}
ldb_ldif_read_free(ldb, ldif);
}
return ret;
}
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
int i, ret=0, count=0;
struct ldb_cmdline *options;
ldb_global_init();
ldb = ldb_init(NULL);
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (options->argc == 0) {
ret = process_file(ldb, stdin, &count);
} else {
for (i=0;i<options->argc;i++) {
const char *fname = options->argv[i];
FILE *f;
f = fopen(fname, "r");
if (!f) {
perror(fname);
exit(1);
}
ret = process_file(ldb, f, &count);
fclose(f);
}
}
talloc_free(ldb);
printf("Added %d records with %d failures\n", count, failures);
return ret;
}
+119
View File
@@ -0,0 +1,119 @@
/*
ldb database library
Copyright (C) Andrew Tridgell 2004
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ldbdel
*
* Description: utility to delete records - modelled on ldapdelete
*
* Author: Andrew Tridgell
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn)
{
int ret, i, total=0;
const char *attrs[] = { NULL };
struct ldb_result *res;
ret = ldb_search(ldb, dn, LDB_SCOPE_SUBTREE, "distinguishedName=*", attrs, &res);
if (ret != LDB_SUCCESS) return -1;
for (i = 0; i < res->count; i++) {
if (ldb_delete(ldb, res->msgs[i]->dn) == 0) {
total++;
}
}
talloc_free(res);
if (total == 0) {
return -1;
}
printf("Deleted %d records\n", total);
return 0;
}
static void usage(void)
{
printf("Usage: ldbdel <options> <DN...>\n");
printf("Options:\n");
printf(" -r recursively delete the given subtree\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
printf(" -o options pass options like modules to activate\n");
printf(" e.g: -o modules:timestamps\n");
printf("\n");
printf("Deletes records from a ldb\n\n");
exit(1);
}
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
int ret = 0, i;
struct ldb_cmdline *options;
ldb_global_init();
ldb = ldb_init(NULL);
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (options->argc < 1) {
usage();
exit(1);
}
for (i=0;i<options->argc;i++) {
struct ldb_dn *dn;
dn = ldb_dn_new(ldb, ldb, options->argv[i]);
if ( ! ldb_dn_validate(dn)) {
printf("Invalid DN format\n");
exit(1);
}
if (options->recursive) {
ret = ldb_delete_recursive(ldb, dn);
} else {
ret = ldb_delete(ldb, dn);
if (ret == 0) {
printf("Deleted 1 record\n");
}
}
if (ret != 0) {
printf("delete of '%s' failed - %s\n",
ldb_dn_get_linearized(dn),
ldb_errstring(ldb));
}
}
talloc_free(ldb);
return ret;
}
+333
View File
@@ -0,0 +1,333 @@
/*
ldb database library
Copyright (C) Andrew Tridgell 2004
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ldbedit
*
* Description: utility for ldb database editing
*
* Author: Andrew Tridgell
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
static struct ldb_cmdline *options;
/*
debug routine
*/
static void ldif_write_msg(struct ldb_context *ldb,
FILE *f,
enum ldb_changetype changetype,
struct ldb_message *msg)
{
struct ldb_ldif ldif;
ldif.changetype = changetype;
ldif.msg = msg;
ldb_ldif_write_file(ldb, f, &ldif);
}
/*
modify a database record so msg1 becomes msg2
returns the number of modified elements
*/
static int modify_record(struct ldb_context *ldb,
struct ldb_message *msg1,
struct ldb_message *msg2)
{
struct ldb_message *mod;
mod = ldb_msg_diff(ldb, msg1, msg2);
if (mod == NULL) {
fprintf(stderr, "Failed to calculate message differences\n");
return -1;
}
if (mod->num_elements == 0) {
return 0;
}
if (options->verbose > 0) {
ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod);
}
if (ldb_modify(ldb, mod) != 0) {
fprintf(stderr, "failed to modify %s - %s\n",
ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb));
return -1;
}
return mod->num_elements;
}
/*
find dn in msgs[]
*/
static struct ldb_message *msg_find(struct ldb_context *ldb,
struct ldb_message **msgs,
int count,
struct ldb_dn *dn)
{
int i;
for (i=0;i<count;i++) {
if (ldb_dn_compare(dn, msgs[i]->dn) == 0) {
return msgs[i];
}
}
return NULL;
}
/*
merge the changes in msgs2 into the messages from msgs1
*/
static int merge_edits(struct ldb_context *ldb,
struct ldb_message **msgs1, int count1,
struct ldb_message **msgs2, int count2)
{
int i;
struct ldb_message *msg;
int ret = 0;
int adds=0, modifies=0, deletes=0;
/* do the adds and modifies */
for (i=0;i<count2;i++) {
msg = msg_find(ldb, msgs1, count1, msgs2[i]->dn);
if (!msg) {
if (options->verbose > 0) {
ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]);
}
if (ldb_add(ldb, msgs2[i]) != 0) {
fprintf(stderr, "failed to add %s - %s\n",
ldb_dn_get_linearized(msgs2[i]->dn),
ldb_errstring(ldb));
return -1;
}
adds++;
} else {
if (modify_record(ldb, msg, msgs2[i]) > 0) {
modifies++;
}
}
}
/* do the deletes */
for (i=0;i<count1;i++) {
msg = msg_find(ldb, msgs2, count2, msgs1[i]->dn);
if (!msg) {
if (options->verbose > 0) {
ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]);
}
if (ldb_delete(ldb, msgs1[i]->dn) != 0) {
fprintf(stderr, "failed to delete %s - %s\n",
ldb_dn_get_linearized(msgs1[i]->dn),
ldb_errstring(ldb));
return -1;
}
deletes++;
}
}
printf("# %d adds %d modifies %d deletes\n", adds, modifies, deletes);
return ret;
}
/*
save a set of messages as ldif to a file
*/
static int save_ldif(struct ldb_context *ldb,
FILE *f, struct ldb_message **msgs, int count)
{
int i;
fprintf(f, "# editing %d records\n", count);
for (i=0;i<count;i++) {
struct ldb_ldif ldif;
fprintf(f, "# record %d\n", i+1);
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = msgs[i];
ldb_ldif_write_file(ldb, f, &ldif);
}
return 0;
}
/*
edit the ldb search results in msgs using the user selected editor
*/
static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int count1,
const char *editor)
{
int fd, ret;
FILE *f;
char file_template[] = "/tmp/ldbedit.XXXXXX";
char *cmd;
struct ldb_ldif *ldif;
struct ldb_message **msgs2 = NULL;
int count2 = 0;
/* write out the original set of messages to a temporary
file */
fd = mkstemp(file_template);
if (fd == -1) {
perror(file_template);
return -1;
}
f = fdopen(fd, "r+");
if (!f) {
perror("fopen");
close(fd);
unlink(file_template);
return -1;
}
if (save_ldif(ldb, f, msgs1, count1) != 0) {
return -1;
}
fclose(f);
cmd = talloc_asprintf(ldb, "%s %s", editor, file_template);
if (!cmd) {
unlink(file_template);
fprintf(stderr, "out of memory\n");
return -1;
}
/* run the editor */
ret = system(cmd);
talloc_free(cmd);
if (ret != 0) {
unlink(file_template);
fprintf(stderr, "edit with %s failed\n", editor);
return -1;
}
/* read the resulting ldif into msgs2 */
f = fopen(file_template, "r");
if (!f) {
perror(file_template);
return -1;
}
while ((ldif = ldb_ldif_read_file(ldb, f))) {
msgs2 = talloc_realloc(ldb, msgs2, struct ldb_message *, count2+1);
if (!msgs2) {
fprintf(stderr, "out of memory");
return -1;
}
msgs2[count2++] = ldif->msg;
}
fclose(f);
unlink(file_template);
return merge_edits(ldb, msgs1, count1, msgs2, count2);
}
static void usage(void)
{
printf("Usage: ldbedit <options> <expression> <attributes ...>\n");
printf("Options:\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
printf(" -s base|sub|one choose search scope\n");
printf(" -b basedn choose baseDN\n");
printf(" -a edit all records (expression 'objectclass=*')\n");
printf(" -e editor choose editor (or $VISUAL or $EDITOR)\n");
printf(" -v verbose mode\n");
exit(1);
}
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
struct ldb_result *result = NULL;
struct ldb_dn *basedn = NULL;
int ret;
const char *expression = "(|(objectClass=*)(distinguishedName=*))";
const char * const * attrs = NULL;
ldb_global_init();
ldb = ldb_init(NULL);
options = ldb_cmdline_process(ldb, argc, argv, usage);
/* the check for '=' is for compatibility with ldapsearch */
if (options->argc > 0 &&
strchr(options->argv[0], '=')) {
expression = options->argv[0];
options->argv++;
options->argc--;
}
if (options->argc > 0) {
attrs = (const char * const *)(options->argv);
}
if (options->basedn != NULL) {
basedn = ldb_dn_new(ldb, ldb, options->basedn);
if ( ! ldb_dn_validate(basedn)) {
printf("Invalid Base DN format\n");
exit(1);
}
}
ret = ldb_search(ldb, basedn, options->scope, expression, attrs, &result);
if (ret != LDB_SUCCESS) {
printf("search failed - %s\n", ldb_errstring(ldb));
exit(1);
}
if (result->count == 0) {
printf("no matching records - cannot edit\n");
return 0;
}
do_edit(ldb, result->msgs, result->count, options->editor);
if (result) {
ret = talloc_free(result);
if (ret == -1) {
fprintf(stderr, "talloc_free failed\n");
exit(1);
}
}
talloc_free(ldb);
return 0;
}
+120
View File
@@ -0,0 +1,120 @@
/*
ldb database library
Copyright (C) Andrew Tridgell 2004
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ldbmodify
*
* Description: utility to modify records - modelled on ldapmodify
*
* Author: Andrew Tridgell
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
static int failures;
static void usage(void)
{
printf("Usage: ldbmodify <options> <ldif...>\n");
printf("Options:\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
printf(" -o options pass options like modules to activate\n");
printf(" e.g: -o modules:timestamps\n");
printf("\n");
printf("Modifies a ldb based upon ldif change records\n\n");
exit(1);
}
/*
process modifies for one file
*/
static int process_file(struct ldb_context *ldb, FILE *f, int *count)
{
struct ldb_ldif *ldif;
int ret = LDB_SUCCESS;
while ((ldif = ldb_ldif_read_file(ldb, f))) {
switch (ldif->changetype) {
case LDB_CHANGETYPE_NONE:
case LDB_CHANGETYPE_ADD:
ret = ldb_add(ldb, ldif->msg);
break;
case LDB_CHANGETYPE_DELETE:
ret = ldb_delete(ldb, ldif->msg->dn);
break;
case LDB_CHANGETYPE_MODIFY:
ret = ldb_modify(ldb, ldif->msg);
break;
}
if (ret != LDB_SUCCESS) {
fprintf(stderr, "ERR: \"%s\" on DN %s\n",
ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn));
failures++;
} else {
(*count)++;
}
ldb_ldif_read_free(ldb, ldif);
}
return ret;
}
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
int count=0;
int i, ret=LDB_SUCCESS;
struct ldb_cmdline *options;
ldb_global_init();
ldb = ldb_init(NULL);
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (options->argc == 0) {
ret = process_file(ldb, stdin, &count);
} else {
for (i=0;i<options->argc;i++) {
const char *fname = options->argv[i];
FILE *f;
f = fopen(fname, "r");
if (!f) {
perror(fname);
exit(1);
}
ret = process_file(ldb, f, &count);
}
}
talloc_free(ldb);
printf("Modified %d records with %d failures\n", count, failures);
return ret;
}
+94
View File
@@ -0,0 +1,94 @@
/*
ldb database library
Copyright (C) Andrew Tridgell 2004
Copyright (C) Stefan Metzmacher 2004
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ldbrename
*
* Description: utility to rename records - modelled on ldapmodrdn
*
* Author: Andrew Tridgell
* Author: Stefan Metzmacher
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
static void usage(void)
{
printf("Usage: ldbrename [<options>] <olddn> <newdn>\n");
printf("Options:\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
printf(" -o options pass options like modules to activate\n");
printf(" e.g: -o modules:timestamps\n");
printf("\n");
printf("Renames records in a ldb\n\n");
exit(1);
}
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
int ret;
struct ldb_cmdline *options;
struct ldb_dn *dn1, *dn2;
ldb_global_init();
ldb = ldb_init(NULL);
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (options->argc < 2) {
usage();
}
dn1 = ldb_dn_new(ldb, ldb, options->argv[0]);
dn2 = ldb_dn_new(ldb, ldb, options->argv[1]);
if ( ! ldb_dn_validate(dn1)) {
printf("Invalid DN1: %s\n", options->argv[0]);
return -1;
}
if ( ! ldb_dn_validate(dn2)) {
printf("Invalid DN2: %s\n", options->argv[1]);
return -1;
}
ret = ldb_rename(ldb, dn1, dn2);
if (ret == 0) {
printf("Renamed 1 record\n");
} else {
printf("rename of '%s' to '%s' failed - %s\n",
options->argv[0], options->argv[1], ldb_errstring(ldb));
}
talloc_free(ldb);
return ret;
}
+320
View File
@@ -0,0 +1,320 @@
/*
ldb database library
Copyright (C) Andrew Tridgell 2004
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ldbsearch
*
* Description: utility for ldb search - modelled on ldapsearch
*
* Author: Andrew Tridgell
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
static void usage(void)
{
printf("Usage: ldbsearch <options> <expression> <attrs...>\n");
printf("Options:\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
printf(" -s base|sub|one choose search scope\n");
printf(" -b basedn choose baseDN\n");
printf(" -i read search expressions from stdin\n");
printf(" -S sort returned attributes\n");
printf(" -o options pass options like modules to activate\n");
printf(" e.g: -o modules:timestamps\n");
exit(1);
}
static int do_compare_msg(struct ldb_message **el1,
struct ldb_message **el2,
void *opaque)
{
return ldb_dn_compare((*el1)->dn, (*el2)->dn);
}
struct search_context {
struct ldb_control **req_ctrls;
int sort;
int num_stored;
struct ldb_message **store;
char **refs_store;
int entries;
int refs;
int pending;
int status;
};
static int store_message(struct ldb_message *msg, struct search_context *sctx) {
sctx->store = talloc_realloc(sctx, sctx->store, struct ldb_message *, sctx->num_stored + 2);
if (!sctx->store) {
fprintf(stderr, "talloc_realloc failed while storing messages\n");
return -1;
}
sctx->store[sctx->num_stored] = talloc_move(sctx->store, &msg);
sctx->num_stored++;
sctx->store[sctx->num_stored] = NULL;
return 0;
}
static int store_referral(char *referral, struct search_context *sctx) {
sctx->refs_store = talloc_realloc(sctx, sctx->refs_store, char *, sctx->refs + 2);
if (!sctx->refs_store) {
fprintf(stderr, "talloc_realloc failed while storing referrals\n");
return -1;
}
sctx->refs_store[sctx->refs] = talloc_move(sctx->refs_store, &referral);
sctx->refs++;
sctx->refs_store[sctx->refs] = NULL;
return 0;
}
static int display_message(struct ldb_context *ldb, struct ldb_message *msg, struct search_context *sctx) {
struct ldb_ldif ldif;
sctx->entries++;
printf("# record %d\n", sctx->entries);
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = msg;
if (sctx->sort) {
/*
* Ensure attributes are always returned in the same
* order. For testing, this makes comparison of old
* vs. new much easier.
*/
ldb_msg_sort_elements(ldif.msg);
}
ldb_ldif_write_file(ldb, stdout, &ldif);
return 0;
}
static int display_referral(char *referral, struct search_context *sctx)
{
sctx->refs++;
printf("# Referral\nref: %s\n\n", referral);
return 0;
}
static int search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
{
struct search_context *sctx = talloc_get_type(context, struct search_context);
int ret;
switch (ares->type) {
case LDB_REPLY_ENTRY:
if (sctx->sort) {
ret = store_message(ares->message, sctx);
} else {
ret = display_message(ldb, ares->message, sctx);
}
break;
case LDB_REPLY_REFERRAL:
if (sctx->sort) {
ret = store_referral(ares->referral, sctx);
} else {
ret = display_referral(ares->referral, sctx);
}
break;
case LDB_REPLY_DONE:
if (ares->controls) {
if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1)
sctx->pending = 1;
}
ret = 0;
break;
default:
fprintf(stderr, "unknown Reply Type\n");
return LDB_ERR_OTHER;
}
if (talloc_free(ares) == -1) {
fprintf(stderr, "talloc_free failed\n");
sctx->pending = 0;
return LDB_ERR_OPERATIONS_ERROR;
}
if (ret) {
return LDB_ERR_OPERATIONS_ERROR;
}
return LDB_SUCCESS;
}
static int do_search(struct ldb_context *ldb,
struct ldb_dn *basedn,
struct ldb_cmdline *options,
const char *expression,
const char * const *attrs)
{
struct ldb_request *req;
struct search_context *sctx;
int ret;
req = talloc(ldb, struct ldb_request);
if (!req) return -1;
sctx = talloc(req, struct search_context);
if (!sctx) return -1;
sctx->sort = options->sorted;
sctx->num_stored = 0;
sctx->store = NULL;
sctx->req_ctrls = parse_controls(ldb, options->controls);
if (options->controls != NULL && sctx->req_ctrls== NULL) return -1;
sctx->entries = 0;
sctx->refs = 0;
if (basedn == NULL) {
basedn = ldb_get_default_basedn(ldb);
}
req->operation = LDB_SEARCH;
req->op.search.base = basedn;
req->op.search.scope = options->scope;
req->op.search.tree = ldb_parse_tree(req, expression);
if (req->op.search.tree == NULL) return -1;
req->op.search.attrs = attrs;
req->controls = sctx->req_ctrls;
req->context = sctx;
req->callback = &search_callback;
ldb_set_timeout(ldb, req, 0); /* TODO: make this settable by command line */
again:
sctx->pending = 0;
ret = ldb_request(ldb, req);
if (ret != LDB_SUCCESS) {
printf("search failed - %s\n", ldb_errstring(ldb));
return -1;
}
ret = ldb_wait(req->handle, LDB_WAIT_ALL);
if (ret != LDB_SUCCESS) {
printf("search error - %s\n", ldb_errstring(ldb));
return -1;
}
if (sctx->pending)
goto again;
if (sctx->sort && sctx->num_stored != 0) {
int i;
ldb_qsort(sctx->store, ret, sizeof(struct ldb_message *),
ldb, (ldb_qsort_cmp_fn_t)do_compare_msg);
if (ret != 0) {
fprintf(stderr, "An error occurred while sorting messages\n");
exit(1);
}
for (i = 0; i < sctx->num_stored; i++) {
display_message(ldb, sctx->store[i], sctx);
}
for (i = 0; i < sctx->refs; i++) {
display_referral(sctx->refs_store[i], sctx);
}
}
printf("# returned %d records\n# %d entries\n# %d referrals\n",
sctx->entries + sctx->refs, sctx->entries, sctx->refs);
talloc_free(req);
return 0;
}
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
struct ldb_dn *basedn = NULL;
const char * const * attrs = NULL;
struct ldb_cmdline *options;
int ret = -1;
const char *expression = "(|(objectClass=*)(distinguishedName=*))";
ldb_global_init();
ldb = ldb_init(NULL);
options = ldb_cmdline_process(ldb, argc, argv, usage);
/* the check for '=' is for compatibility with ldapsearch */
if (!options->interactive &&
options->argc > 0 &&
strchr(options->argv[0], '=')) {
expression = options->argv[0];
options->argv++;
options->argc--;
}
if (options->argc > 0) {
attrs = (const char * const *)(options->argv);
}
if (options->basedn != NULL) {
basedn = ldb_dn_new(ldb, ldb, options->basedn);
if ( ! ldb_dn_validate(basedn)) {
fprintf(stderr, "Invalid Base DN format\n");
exit(1);
}
}
if (options->interactive) {
char line[1024];
while (fgets(line, sizeof(line), stdin)) {
if (do_search(ldb, basedn, options, line, attrs) == -1) {
ret = -1;
}
}
} else {
ret = do_search(ldb, basedn, options, expression, attrs);
}
talloc_free(ldb);
return ret;
}
+422
View File
@@ -0,0 +1,422 @@
/*
ldb database library
Copyright (C) Andrew Tridgell 2004
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: ldbtest
*
* Description: utility to test ldb
*
* Author: Andrew Tridgell
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
static struct timeval tp1,tp2;
static struct ldb_cmdline *options;
static void _start_timer(void)
{
gettimeofday(&tp1,NULL);
}
static double _end_timer(void)
{
gettimeofday(&tp2,NULL);
return((tp2.tv_sec - tp1.tv_sec) +
(tp2.tv_usec - tp1.tv_usec)*1.0e-6);
}
static void add_records(struct ldb_context *ldb,
struct ldb_dn *basedn,
int count)
{
struct ldb_message msg;
int i;
#if 0
if (ldb_lock(ldb, "transaction") != 0) {
printf("transaction lock failed\n");
exit(1);
}
#endif
for (i=0;i<count;i++) {
struct ldb_message_element el[6];
struct ldb_val vals[6][1];
char *name;
TALLOC_CTX *tmp_ctx = talloc_new(ldb);
name = talloc_asprintf(tmp_ctx, "Test%d", i);
msg.dn = ldb_dn_copy(tmp_ctx, basedn);
ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
msg.num_elements = 6;
msg.elements = el;
el[0].flags = 0;
el[0].name = talloc_strdup(tmp_ctx, "cn");
el[0].num_values = 1;
el[0].values = vals[0];
vals[0][0].data = (uint8_t *)name;
vals[0][0].length = strlen(name);
el[1].flags = 0;
el[1].name = "title";
el[1].num_values = 1;
el[1].values = vals[1];
vals[1][0].data = (uint8_t *)talloc_asprintf(tmp_ctx, "The title of %s", name);
vals[1][0].length = strlen((char *)vals[1][0].data);
el[2].flags = 0;
el[2].name = talloc_strdup(tmp_ctx, "uid");
el[2].num_values = 1;
el[2].values = vals[2];
vals[2][0].data = (uint8_t *)ldb_casefold(ldb, tmp_ctx, name);
vals[2][0].length = strlen((char *)vals[2][0].data);
el[3].flags = 0;
el[3].name = talloc_strdup(tmp_ctx, "mail");
el[3].num_values = 1;
el[3].values = vals[3];
vals[3][0].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@example.com", name);
vals[3][0].length = strlen((char *)vals[3][0].data);
el[4].flags = 0;
el[4].name = talloc_strdup(tmp_ctx, "objectClass");
el[4].num_values = 1;
el[4].values = vals[4];
vals[4][0].data = (uint8_t *)talloc_strdup(tmp_ctx, "OpenLDAPperson");
vals[4][0].length = strlen((char *)vals[4][0].data);
el[5].flags = 0;
el[5].name = talloc_strdup(tmp_ctx, "sn");
el[5].num_values = 1;
el[5].values = vals[5];
vals[5][0].data = (uint8_t *)name;
vals[5][0].length = strlen((char *)vals[5][0].data);
ldb_delete(ldb, msg.dn);
if (ldb_add(ldb, &msg) != 0) {
printf("Add of %s failed - %s\n", name, ldb_errstring(ldb));
exit(1);
}
printf("adding uid %s\r", name);
fflush(stdout);
talloc_free(tmp_ctx);
}
#if 0
if (ldb_unlock(ldb, "transaction") != 0) {
printf("transaction unlock failed\n");
exit(1);
}
#endif
printf("\n");
}
static void modify_records(struct ldb_context *ldb,
struct ldb_dn *basedn,
int count)
{
struct ldb_message msg;
int i;
for (i=0;i<count;i++) {
struct ldb_message_element el[3];
struct ldb_val vals[3];
char *name;
TALLOC_CTX *tmp_ctx = talloc_new(ldb);
name = talloc_asprintf(tmp_ctx, "Test%d", i);
msg.dn = ldb_dn_copy(tmp_ctx, basedn);
ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
msg.num_elements = 3;
msg.elements = el;
el[0].flags = LDB_FLAG_MOD_DELETE;
el[0].name = talloc_strdup(tmp_ctx, "mail");
el[0].num_values = 0;
el[1].flags = LDB_FLAG_MOD_ADD;
el[1].name = talloc_strdup(tmp_ctx, "mail");
el[1].num_values = 1;
el[1].values = &vals[1];
vals[1].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other.example.com", name);
vals[1].length = strlen((char *)vals[1].data);
el[2].flags = LDB_FLAG_MOD_REPLACE;
el[2].name = talloc_strdup(tmp_ctx, "mail");
el[2].num_values = 1;
el[2].values = &vals[2];
vals[2].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other2.example.com", name);
vals[2].length = strlen((char *)vals[2].data);
if (ldb_modify(ldb, &msg) != 0) {
printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb));
exit(1);
}
printf("Modifying uid %s\r", name);
fflush(stdout);
talloc_free(tmp_ctx);
}
printf("\n");
}
static void delete_records(struct ldb_context *ldb,
struct ldb_dn *basedn,
int count)
{
int i;
for (i=0;i<count;i++) {
struct ldb_dn *dn;
char *name = talloc_asprintf(ldb, "Test%d", i);
dn = ldb_dn_copy(name, basedn);
ldb_dn_add_child_fmt(dn, "cn=%s", name);
printf("Deleting uid Test%d\r", i);
fflush(stdout);
if (ldb_delete(ldb, dn) != 0) {
printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb));
exit(1);
}
talloc_free(name);
}
printf("\n");
}
static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nrecords, int nsearches)
{
int i;
for (i=0;i<nsearches;i++) {
int uid = (i * 700 + 17) % (nrecords * 2);
char *expr;
struct ldb_result *res = NULL;
int ret;
expr = talloc_asprintf(ldb, "(uid=TEST%d)", uid);
ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, expr, NULL, &res);
if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) {
printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb));
exit(1);
}
if (uid >= nrecords && res->count > 0) {
printf("Found %s !? - %d\n", expr, ret);
exit(1);
}
printf("testing uid %d/%d - %d \r", i, uid, res->count);
fflush(stdout);
talloc_free(res);
talloc_free(expr);
}
printf("\n");
}
static void start_test(struct ldb_context *ldb, int nrecords, int nsearches)
{
struct ldb_dn *basedn;
basedn = ldb_dn_new(ldb, ldb, options->basedn);
if ( ! ldb_dn_validate(basedn)) {
printf("Invalid base DN\n");
exit(1);
}
printf("Adding %d records\n", nrecords);
add_records(ldb, basedn, nrecords);
printf("Starting search on uid\n");
_start_timer();
search_uid(ldb, basedn, nrecords, nsearches);
printf("uid search took %.2f seconds\n", _end_timer());
printf("Modifying records\n");
modify_records(ldb, basedn, nrecords);
printf("Deleting records\n");
delete_records(ldb, basedn, nrecords);
}
/*
2) Store an @indexlist record
3) Store a record that contains fields that should be index according
to @index
4) disconnection from database
5) connect to same database
6) search for record added in step 3 using a search key that should
be indexed
*/
static void start_test_index(struct ldb_context **ldb)
{
struct ldb_message *msg;
struct ldb_result *res = NULL;
struct ldb_dn *indexlist;
struct ldb_dn *basedn;
int ret;
int flags = 0;
const char *specials;
specials = getenv("LDB_SPECIALS");
if (specials && atoi(specials) == 0) {
printf("LDB_SPECIALS disabled - skipping index test\n");
return;
}
if (options->nosync) {
flags |= LDB_FLG_NOSYNC;
}
printf("Starting index test\n");
indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
ldb_delete(*ldb, indexlist);
msg = ldb_msg_new(NULL);
msg->dn = indexlist;
ldb_msg_add_string(msg, "@IDXATTR", strdup("uid"));
if (ldb_add(*ldb, msg) != 0) {
printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
exit(1);
}
basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
memset(msg, 0, sizeof(*msg));
msg->dn = ldb_dn_copy(msg, basedn);
ldb_dn_add_child_fmt(msg->dn, "cn=test");
ldb_msg_add_string(msg, "cn", strdup("test"));
ldb_msg_add_string(msg, "sn", strdup("test"));
ldb_msg_add_string(msg, "uid", strdup("test"));
ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson"));
if (ldb_add(*ldb, msg) != 0) {
printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
exit(1);
}
if (talloc_free(*ldb) != 0) {
printf("failed to free/close ldb database");
exit(1);
}
(*ldb) = ldb_init(options);
ret = ldb_connect(*ldb, options->url, flags, NULL);
if (ret != 0) {
printf("failed to connect to %s\n", options->url);
exit(1);
}
basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
ret = ldb_search(*ldb, basedn, LDB_SCOPE_SUBTREE, "uid=test", NULL, &res);
if (ret != LDB_SUCCESS) {
printf("Search with (uid=test) filter failed!\n");
exit(1);
}
if(res->count != 1) {
printf("Should have found 1 record - found %d\n", res->count);
exit(1);
}
indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
if (ldb_delete(*ldb, msg->dn) != 0 ||
ldb_delete(*ldb, indexlist) != 0) {
printf("cleanup failed - %s\n", ldb_errstring(*ldb));
exit(1);
}
printf("Finished index test\n");
}
static void usage(void)
{
printf("Usage: ldbtest <options>\n");
printf("Options:\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
printf(" --num-records nrecords database size to use\n");
printf(" --num-searches nsearches number of searches to do\n");
printf("\n");
printf("tests ldb API\n\n");
exit(1);
}
int main(int argc, const char **argv)
{
TALLOC_CTX *mem_ctx = talloc_new(NULL);
struct ldb_context *ldb;
ldb_global_init();
ldb = ldb_init(mem_ctx);
options = ldb_cmdline_process(ldb, argc, argv, usage);
talloc_steal(mem_ctx, options);
if (options->basedn == NULL) {
options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST";
}
srandom(1);
printf("Testing with num-records=%d and num-searches=%d\n",
options->num_records, options->num_searches);
start_test(ldb, options->num_records, options->num_searches);
start_test_index(&ldb);
talloc_free(mem_ctx);
return 0;
}
+607
View File
@@ -0,0 +1,607 @@
/*
ldb database library
Copyright (C) Simo Sorce 2005
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Name: ldb
*
* Component: oLschema2ldif
*
* Description: utility to convert an OpenLDAP schema into AD LDIF
*
* Author: Simo Sorce
*/
#include "includes.h"
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
#include "ldb/tools/convert.h"
#define SCHEMA_UNKNOWN 0
#define SCHEMA_NAME 1
#define SCHEMA_SUP 2
#define SCHEMA_STRUCTURAL 3
#define SCHEMA_ABSTRACT 4
#define SCHEMA_AUXILIARY 5
#define SCHEMA_MUST 6
#define SCHEMA_MAY 7
#define SCHEMA_SINGLE_VALUE 8
#define SCHEMA_EQUALITY 9
#define SCHEMA_ORDERING 10
#define SCHEMA_SUBSTR 11
#define SCHEMA_SYNTAX 12
#define SCHEMA_DESC 13
struct schema_conv {
int count;
int failures;
};
struct schema_token {
int type;
char *value;
};
struct ldb_context *ldb_ctx;
struct ldb_dn *basedn;
static int check_braces(const char *string)
{
int b;
char *c;
b = 0;
if ((c = strchr(string, '(')) == NULL) {
return -1;
}
b++;
c++;
while (b) {
c = strpbrk(c, "()");
if (c == NULL) return 1;
if (*c == '(') b++;
if (*c == ')') b--;
c++;
}
return 0;
}
static char *skip_spaces(char *string) {
return (string + strspn(string, " \t\n"));
}
static int add_multi_string(struct ldb_message *msg, const char *attr, char *values)
{
char *c;
char *s;
int n;
c = skip_spaces(values);
while (*c) {
n = strcspn(c, " \t$");
s = talloc_strndup(msg, c, n);
if (ldb_msg_add_string(msg, attr, s) != 0) {
return -1;
}
c += n;
c += strspn(c, " \t$");
}
return 0;
}
#define MSG_ADD_STRING(a, v) do { if (ldb_msg_add_string(msg, a, v) != 0) goto failed; } while(0)
#define MSG_ADD_M_STRING(a, v) do { if (add_multi_string(msg, a, v) != 0) goto failed; } while(0)
static char *get_def_value(TALLOC_CTX *ctx, char **string)
{
char *c = *string;
char *value;
int n;
if (*c == '\'') {
c++;
n = strcspn(c, "\'");
value = talloc_strndup(ctx, c, n);
c += n;
c++; /* skip closing \' */
} else {
n = strcspn(c, " \t\n");
value = talloc_strndup(ctx, c, n);
c += n;
}
*string = c;
return value;
}
static struct schema_token *get_next_schema_token(TALLOC_CTX *ctx, char **string)
{
char *c = skip_spaces(*string);
char *type;
struct schema_token *token;
int n;
token = talloc(ctx, struct schema_token);
n = strcspn(c, " \t\n");
type = talloc_strndup(token, c, n);
c += n;
c = skip_spaces(c);
if (strcasecmp("NAME", type) == 0) {
talloc_free(type);
token->type = SCHEMA_NAME;
/* we do not support aliases so we get only the first name given and skip others */
if (*c == '(') {
char *s = strchr(c, ')');
if (s == NULL) return NULL;
s = skip_spaces(s);
*string = s;
c++;
c = skip_spaces(c);
}
token->value = get_def_value(ctx, &c);
if (*string < c) { /* single name */
c = skip_spaces(c);
*string = c;
}
return token;
}
if (strcasecmp("SUP", type) == 0) {
talloc_free(type);
token->type = SCHEMA_SUP;
if (*c == '(') {
c++;
n = strcspn(c, ")");
token->value = talloc_strndup(ctx, c, n);
c += n;
c++;
} else {
token->value = get_def_value(ctx, &c);
}
c = skip_spaces(c);
*string = c;
return token;
}
if (strcasecmp("STRUCTURAL", type) == 0) {
talloc_free(type);
token->type = SCHEMA_STRUCTURAL;
*string = c;
return token;
}
if (strcasecmp("ABSTRACT", type) == 0) {
talloc_free(type);
token->type = SCHEMA_ABSTRACT;
*string = c;
return token;
}
if (strcasecmp("AUXILIARY", type) == 0) {
talloc_free(type);
token->type = SCHEMA_AUXILIARY;
*string = c;
return token;
}
if (strcasecmp("MUST", type) == 0) {
talloc_free(type);
token->type = SCHEMA_MUST;
if (*c == '(') {
c++;
n = strcspn(c, ")");
token->value = talloc_strndup(ctx, c, n);
c += n;
c++;
} else {
token->value = get_def_value(ctx, &c);
}
c = skip_spaces(c);
*string = c;
return token;
}
if (strcasecmp("MAY", type) == 0) {
talloc_free(type);
token->type = SCHEMA_MAY;
if (*c == '(') {
c++;
n = strcspn(c, ")");
token->value = talloc_strndup(ctx, c, n);
c += n;
c++;
} else {
token->value = get_def_value(ctx, &c);
}
c = skip_spaces(c);
*string = c;
return token;
}
if (strcasecmp("SINGLE-VALUE", type) == 0) {
talloc_free(type);
token->type = SCHEMA_SINGLE_VALUE;
*string = c;
return token;
}
if (strcasecmp("EQUALITY", type) == 0) {
talloc_free(type);
token->type = SCHEMA_EQUALITY;
token->value = get_def_value(ctx, &c);
c = skip_spaces(c);
*string = c;
return token;
}
if (strcasecmp("ORDERING", type) == 0) {
talloc_free(type);
token->type = SCHEMA_ORDERING;
token->value = get_def_value(ctx, &c);
c = skip_spaces(c);
*string = c;
return token;
}
if (strcasecmp("SUBSTR", type) == 0) {
talloc_free(type);
token->type = SCHEMA_SUBSTR;
token->value = get_def_value(ctx, &c);
c = skip_spaces(c);
*string = c;
return token;
}
if (strcasecmp("SYNTAX", type) == 0) {
talloc_free(type);
token->type = SCHEMA_SYNTAX;
token->value = get_def_value(ctx, &c);
c = skip_spaces(c);
*string = c;
return token;
}
if (strcasecmp("DESC", type) == 0) {
talloc_free(type);
token->type = SCHEMA_DESC;
token->value = get_def_value(ctx, &c);
c = skip_spaces(c);
*string = c;
return token;
}
token->type = SCHEMA_UNKNOWN;
token->value = type;
if (*c == ')') {
*string = c;
return token;
}
if (*c == '\'') {
c = strchr(++c, '\'');
c++;
} else {
c += strcspn(c, " \t\n");
}
c = skip_spaces(c);
*string = c;
return token;
}
static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry)
{
TALLOC_CTX *ctx;
struct ldb_message *msg;
struct schema_token *token;
char *c, *s;
int n;
ctx = talloc_new(mem_ctx);
msg = ldb_msg_new(ctx);
ldb_msg_add_string(msg, "objectClass", "top");
c = talloc_strdup(ctx, entry);
if (!c) return NULL;
c = skip_spaces(c);
switch (*c) {
case 'a':
if (strncmp(c, "attributetype", 13) == 0) {
c += 13;
MSG_ADD_STRING("objectClass", "attributeSchema");
break;
}
goto failed;
case 'o':
if (strncmp(c, "objectclass", 11) == 0) {
c += 11;
MSG_ADD_STRING("objectClass", "classSchema");
break;
}
goto failed;
default:
goto failed;
}
c = strchr(c, '(');
if (c == NULL) goto failed;
c++;
c = skip_spaces(c);
/* get attributeID */
n = strcspn(c, " \t");
s = talloc_strndup(msg, c, n);
MSG_ADD_STRING("attributeID", s);
c += n;
c = skip_spaces(c);
while (*c != ')') {
token = get_next_schema_token(msg, &c);
if (!token) goto failed;
switch (token->type) {
case SCHEMA_NAME:
MSG_ADD_STRING("cn", token->value);
MSG_ADD_STRING("name", token->value);
MSG_ADD_STRING("lDAPDisplayName", token->value);
msg->dn = ldb_dn_copy(msg, basedn);
ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Schema,CN=Configuration", token->value);
break;
case SCHEMA_SUP:
MSG_ADD_M_STRING("subClassOf", token->value);
break;
case SCHEMA_STRUCTURAL:
MSG_ADD_STRING("objectClassCategory", "1");
break;
case SCHEMA_ABSTRACT:
MSG_ADD_STRING("objectClassCategory", "2");
break;
case SCHEMA_AUXILIARY:
MSG_ADD_STRING("objectClassCategory", "3");
break;
case SCHEMA_MUST:
MSG_ADD_M_STRING("mustContain", token->value);
break;
case SCHEMA_MAY:
MSG_ADD_M_STRING("mayContain", token->value);
break;
case SCHEMA_SINGLE_VALUE:
MSG_ADD_STRING("isSingleValued", "TRUE");
break;
case SCHEMA_EQUALITY:
/* TODO */
break;
case SCHEMA_ORDERING:
/* TODO */
break;
case SCHEMA_SUBSTR:
/* TODO */
break;
case SCHEMA_SYNTAX:
{
const struct syntax_map *map =
find_syntax_map_by_standard_oid(token->value);
if (!map) {
break;
}
MSG_ADD_STRING("attributeSyntax", map->AD_OID);
break;
}
case SCHEMA_DESC:
MSG_ADD_STRING("description", token->value);
break;
default:
fprintf(stderr, "Unknown Definition: %s\n", token->value);
}
}
talloc_steal(mem_ctx, msg);
talloc_free(ctx);
return msg;
failed:
talloc_free(ctx);
return NULL;
}
static struct schema_conv process_file(FILE *in, FILE *out)
{
TALLOC_CTX *ctx;
struct schema_conv ret;
char *entry;
int c, t, line;
struct ldb_ldif ldif;
ldif.changetype = LDB_CHANGETYPE_NONE;
ctx = talloc_new(NULL);
ret.count = 0;
ret.failures = 0;
line = 0;
while ((c = fgetc(in)) != EOF) {
line++;
/* fprintf(stderr, "Parsing line %d\n", line); */
if (c == '#') {
do {
c = fgetc(in);
} while (c != EOF && c != '\n');
continue;
}
if (c == '\n') {
continue;
}
t = 0;
entry = talloc_array(ctx, char, 1024);
if (entry == NULL) exit(-1);
do {
if (c == '\n') {
entry[t] = '\0';
if (check_braces(entry) == 0) {
ret.count++;
ldif.msg = process_entry(ctx, entry);
if (ldif.msg == NULL) {
ret.failures++;
fprintf(stderr, "No valid msg from entry \n[%s]\n at line %d\n", entry, line);
break;
}
ldb_ldif_write_file(ldb_ctx, out, &ldif);
break;
}
line++;
} else {
entry[t] = c;
t++;
}
if ((t % 1023) == 0) {
entry = talloc_realloc(ctx, entry, char, t + 1024);
if (entry == NULL) exit(-1);
}
} while ((c = fgetc(in)) != EOF);
if (c != '\n') {
entry[t] = '\0';
if (check_braces(entry) == 0) {
ret.count++;
ldif.msg = process_entry(ctx, entry);
if (ldif.msg == NULL) {
ret.failures++;
fprintf(stderr, "No valid msg from entry \n[%s]\n at line %d\n", entry, line);
break;
}
ldb_ldif_write_file(ldb_ctx, out, &ldif);
} else {
fprintf(stderr, "malformed entry on line %d\n", line);
ret.failures++;
}
}
if (c == EOF) break;
}
return ret;
}
static void usage(void)
{
printf("Usage: oLschema2ldif -H NONE <options>\n");
printf("\nConvert OpenLDAP schema to AD-like LDIF format\n\n");
printf("Options:\n");
printf(" -I inputfile inputfile of OpenLDAP style schema otherwise STDIN\n");
printf(" -O outputfile outputfile otherwise STDOUT\n");
printf(" -o options pass options like modules to activate\n");
printf(" e.g: -o modules:timestamps\n");
printf("\n");
printf("Converts records from an openLdap formatted schema to an ldif schema\n\n");
exit(1);
}
int main(int argc, const char **argv)
{
TALLOC_CTX *ctx;
struct schema_conv ret;
struct ldb_cmdline *options;
FILE *in = stdin;
FILE *out = stdout;
ldb_global_init();
ctx = talloc_new(NULL);
ldb_ctx = ldb_init(ctx);
setenv("LDB_URL", "NONE", 1);
options = ldb_cmdline_process(ldb_ctx, argc, argv, usage);
if (options->basedn == NULL) {
perror("Base DN not specified");
exit(1);
} else {
basedn = ldb_dn_new(ctx, ldb_ctx, options->basedn);
if ( ! ldb_dn_validate(basedn)) {
perror("Malformed Base DN");
exit(1);
}
}
if (options->input) {
in = fopen(options->input, "r");
if (!in) {
perror(options->input);
exit(1);
}
}
if (options->output) {
out = fopen(options->output, "w");
if (!out) {
perror(options->output);
exit(1);
}
}
ret = process_file(in, out);
fclose(in);
fclose(out);
printf("Converted %d records with %d failures\n", ret.count, ret.failures);
return 0;
}