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: ldbmodify
28 : *
29 : * Description: utility to modify records - modelled on ldapmodify
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: ldbmodify <options> <ldif...>\n");
45 1 : printf("Modifies a ldb based upon ldif change records\n\n");
46 1 : ldb_cmdline_help(ldb, "ldbmodify", stdout);
47 1 : exit(LDB_ERR_OPERATIONS_ERROR);
48 : }
49 :
50 : /*
51 : process modifies for one file
52 : */
53 422 : static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count)
54 : {
55 46 : struct ldb_ldif *ldif;
56 422 : int fun_ret = LDB_SUCCESS, ret;
57 422 : struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls);
58 422 : struct ldif_read_file_state state = {
59 : .f = f
60 : };
61 :
62 422 : if (options->controls != NULL && req_ctrls== NULL) {
63 0 : printf("parsing controls failed: %s\n", ldb_errstring(ldb));
64 0 : exit(LDB_ERR_OPERATIONS_ERROR);
65 : }
66 :
67 422 : fun_ret = ldb_transaction_start(ldb);
68 422 : if (fun_ret != LDB_SUCCESS) {
69 0 : fprintf(stderr, "ERR: (%s) on transaction start\n",
70 : ldb_errstring(ldb));
71 0 : return fun_ret;
72 : }
73 :
74 5831 : while ((ldif = ldb_ldif_read_file_state(ldb, &state))) {
75 65 : struct ldb_dn *olddn;
76 5410 : bool deleteoldrdn = false;
77 65 : struct ldb_dn *newdn;
78 5410 : const char *errstr = NULL;
79 :
80 5410 : switch (ldif->changetype) {
81 2502 : case LDB_CHANGETYPE_NONE:
82 : case LDB_CHANGETYPE_ADD:
83 2502 : ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls);
84 2502 : break;
85 2478 : case LDB_CHANGETYPE_DELETE:
86 2478 : ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls);
87 2478 : break;
88 426 : case LDB_CHANGETYPE_MODIFY:
89 426 : ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls);
90 426 : break;
91 4 : case LDB_CHANGETYPE_MODRDN:
92 4 : ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, &olddn,
93 : NULL, &deleteoldrdn,
94 : NULL, &newdn);
95 4 : if (ret == LDB_SUCCESS) {
96 4 : if (deleteoldrdn) {
97 4 : ret = ldb_rename(ldb, olddn, newdn);
98 : } else {
99 0 : errstr = "modrdn: deleteoldrdn=0 "
100 : "not supported.";
101 0 : ret = LDB_ERR_CONSTRAINT_VIOLATION;
102 : }
103 : }
104 1 : break;
105 0 : default:
106 0 : ret = LDB_ERR_PROTOCOL_ERROR;
107 0 : break;
108 : }
109 5410 : if (ret != LDB_SUCCESS) {
110 1 : if (errstr == NULL) {
111 1 : errstr = ldb_errstring(ldb);
112 : }
113 1 : fprintf(stderr,
114 : "ERR: (%s) \"%s\" on DN %s at block before "
115 : "line %zu\n",
116 : ldb_strerror(ret),
117 : errstr,
118 1 : ldb_dn_get_linearized(ldif->msg->dn),
119 : state.line_no);
120 1 : fun_ret = ret;
121 : } else {
122 5409 : (*count)++;
123 5409 : if (options->verbose) {
124 2 : printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn));
125 : }
126 : }
127 5410 : ldb_ldif_read_free(ldb, ldif);
128 5410 : if (ret) {
129 0 : break;
130 : }
131 : }
132 :
133 422 : if (fun_ret == LDB_SUCCESS && !feof(f)) {
134 0 : fprintf(stderr, "Failed to parse ldif\n");
135 0 : fun_ret = LDB_ERR_OPERATIONS_ERROR;
136 : }
137 :
138 422 : if (fun_ret == LDB_SUCCESS) {
139 421 : fun_ret = ldb_transaction_commit(ldb);
140 421 : if (fun_ret != LDB_SUCCESS) {
141 0 : fprintf(stderr, "ERR: (%s) on transaction commit\n",
142 : ldb_errstring(ldb));
143 : }
144 : } else {
145 1 : ldb_transaction_cancel(ldb);
146 : }
147 :
148 376 : return fun_ret;
149 : }
150 :
151 412 : int main(int argc, const char **argv)
152 : {
153 46 : struct ldb_context *ldb;
154 412 : unsigned int i, count = 0;
155 412 : int ret = LDB_SUCCESS;
156 412 : TALLOC_CTX *mem_ctx = talloc_new(NULL);
157 :
158 412 : ldb = ldb_init(mem_ctx, NULL);
159 412 : if (ldb == NULL) {
160 0 : return LDB_ERR_OPERATIONS_ERROR;
161 : }
162 :
163 412 : options = ldb_cmdline_process(ldb, argc, argv, usage);
164 :
165 410 : if (options->argc == 0) {
166 325 : ret = process_file(ldb, stdin, &count);
167 : } else {
168 182 : for (i=0;i<options->argc;i++) {
169 97 : const char *fname = options->argv[i];
170 23 : FILE *f;
171 97 : f = fopen(fname, "r");
172 97 : if (!f) {
173 0 : perror(fname);
174 0 : return LDB_ERR_OPERATIONS_ERROR;
175 : }
176 97 : ret = process_file(ldb, f, &count);
177 97 : fclose(f);
178 : }
179 : }
180 :
181 410 : talloc_free(mem_ctx);
182 :
183 410 : if (ret) {
184 1 : printf("Modify failed after processing %u records\n", count);
185 : } else {
186 409 : printf("Modified %u records successfully\n", count);
187 : }
188 :
189 364 : return ret;
190 : }
|