Line data Source code
1 : /*
2 : ldb database library
3 :
4 : Copyright (C) Andrew Tridgell 2004
5 :
6 : ** NOTE! The following LGPL license applies to the ldb
7 : ** library. This does NOT imply that all of Samba is released
8 : ** under the LGPL
9 :
10 : This library is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU Lesser General Public
12 : License as published by the Free Software Foundation; either
13 : version 3 of the License, or (at your option) any later version.
14 :
15 : This library is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 : Lesser General Public License for more details.
19 :
20 : You should have received a copy of the GNU Lesser General Public
21 : License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : /*
25 : * Name: ldb
26 : *
27 : * Component: ldbadd
28 : *
29 : * Description: utility to add records - modelled on ldapadd
30 : *
31 : * Author: Andrew Tridgell
32 : */
33 :
34 : #include "replace.h"
35 : #include "ldb.h"
36 : #include "tools/cmdline.h"
37 : #include "ldbutil.h"
38 : #include "include/ldb_private.h"
39 :
40 : static struct ldb_cmdline *options;
41 :
42 1 : static void usage(struct ldb_context *ldb)
43 : {
44 1 : printf("Usage: ldbadd <options> <ldif...>\n");
45 1 : printf("Adds records to a ldb, reading ldif the specified list of files\n\n");
46 1 : ldb_cmdline_help(ldb, "ldbadd", stdout);
47 1 : exit(LDB_ERR_OPERATIONS_ERROR);
48 : }
49 :
50 :
51 : /*
52 : add records from an opened file
53 : */
54 168 : static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count)
55 : {
56 29 : struct ldb_ldif *ldif;
57 168 : int fun_ret = LDB_SUCCESS, ret;
58 168 : struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls);
59 168 : struct ldif_read_file_state state = {
60 : .f = f
61 : };
62 :
63 168 : if (options->controls != NULL && req_ctrls== NULL) {
64 0 : printf("parsing controls failed: %s\n", ldb_errstring(ldb));
65 0 : return LDB_ERR_OPERATIONS_ERROR;
66 : }
67 :
68 168 : fun_ret = ldb_transaction_start(ldb);
69 168 : if (fun_ret != LDB_SUCCESS) {
70 0 : fprintf(stderr, "ERR: (%s) on transaction start\n",
71 : ldb_errstring(ldb));
72 0 : return fun_ret;
73 : }
74 :
75 381 : while ((ldif = ldb_ldif_read_file_state(ldb, &state))) {
76 219 : if (ldif->changetype != LDB_CHANGETYPE_ADD &&
77 150 : ldif->changetype != LDB_CHANGETYPE_NONE) {
78 2 : fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n");
79 0 : break;
80 : }
81 :
82 217 : ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg);
83 217 : if (ret != LDB_SUCCESS) {
84 0 : fprintf(stderr,
85 : "ERR: Message canonicalize failed - %s\n",
86 : ldb_strerror(ret));
87 0 : fun_ret = ret;
88 0 : ldb_ldif_read_free(ldb, ldif);
89 0 : continue;
90 : }
91 :
92 217 : ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls);
93 217 : if (ret != LDB_SUCCESS) {
94 4 : fprintf(stderr, "ERR: %s : \"%s\" on DN %s at block before line %llu\n",
95 : ldb_strerror(ret), ldb_errstring(ldb),
96 4 : ldb_dn_get_linearized(ldif->msg->dn),
97 4 : (unsigned long long)state.line_no);
98 4 : fun_ret = ret;
99 : } else {
100 213 : (*count)++;
101 213 : if (options->verbose) {
102 0 : printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn));
103 : }
104 : }
105 217 : ldb_ldif_read_free(ldb, ldif);
106 217 : if (ret) {
107 0 : break;
108 : }
109 : }
110 :
111 168 : if (fun_ret == LDB_SUCCESS && !feof(f)) {
112 2 : fprintf(stderr, "Failed to parse ldif\n");
113 2 : fun_ret = LDB_ERR_OPERATIONS_ERROR;
114 : }
115 :
116 168 : if (fun_ret == LDB_SUCCESS) {
117 162 : fun_ret = ldb_transaction_commit(ldb);
118 162 : if (fun_ret != LDB_SUCCESS) {
119 0 : fprintf(stderr, "ERR: (%s) on transaction commit\n",
120 : ldb_errstring(ldb));
121 : }
122 : } else {
123 6 : ldb_transaction_cancel(ldb);
124 : }
125 :
126 139 : return fun_ret;
127 : }
128 :
129 :
130 :
131 170 : int main(int argc, const char **argv)
132 : {
133 29 : struct ldb_context *ldb;
134 170 : unsigned int i, count = 0;
135 170 : int ret = LDB_SUCCESS;
136 170 : TALLOC_CTX *mem_ctx = talloc_new(NULL);
137 :
138 170 : ldb = ldb_init(mem_ctx, NULL);
139 170 : if (ldb == NULL) {
140 0 : return LDB_ERR_OPERATIONS_ERROR;
141 : }
142 :
143 170 : options = ldb_cmdline_process(ldb, argc, argv, usage);
144 :
145 168 : ret = ldb_transaction_start(ldb);
146 168 : if (ret != LDB_SUCCESS) {
147 0 : printf("Failed to start transaction: %s\n", ldb_errstring(ldb));
148 0 : return ret;
149 : }
150 :
151 168 : if (options->argc == 0) {
152 143 : ret = process_file(ldb, stdin, &count);
153 : } else {
154 50 : for (i=0;i<options->argc;i++) {
155 25 : const char *fname = options->argv[i];
156 16 : FILE *f;
157 25 : f = fopen(fname, "r");
158 25 : if (!f) {
159 0 : perror(fname);
160 0 : return LDB_ERR_OPERATIONS_ERROR;
161 : }
162 25 : ret = process_file(ldb, f, &count);
163 25 : fclose(f);
164 : }
165 : }
166 :
167 168 : if (count != 0) {
168 162 : ret = ldb_transaction_commit(ldb);
169 162 : if (ret != LDB_SUCCESS) {
170 0 : printf("Failed to commit transaction: %s\n", ldb_errstring(ldb));
171 0 : return ret;
172 : }
173 : } else {
174 6 : ldb_transaction_cancel(ldb);
175 : }
176 :
177 168 : talloc_free(mem_ctx);
178 :
179 168 : if (ret) {
180 6 : printf("Add failed after processing %u records\n", count);
181 : } else {
182 162 : printf("Added %u records successfully\n", count);
183 : }
184 :
185 139 : return ret;
186 : }
|