r8486: switched to a separate connection operation in ldb interface
[sfrench/samba-autobuild/.git] / source4 / scripting / ejs / smbcalls_ldb.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    provide hooks into smbd C calls from ejs scripts
5
6    Copyright (C) Andrew Tridgell 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "scripting/ejs/smbcalls.h"
25 #include "lib/appweb/ejs/ejs.h"
26 #include "lib/ldb/include/ldb.h"
27
28 /*
29   get the connected db
30  */
31 static struct ldb_context *ejs_ldb_db(int eid, struct MprVar *v)
32 {
33         struct ldb_context *ldb = mprGetPtr(v, "ldb");
34         if (ldb == NULL) {
35                 ejsSetErrorMsg(eid, "invalid ldb connection");
36         }
37         return ldb;
38 }
39
40 /*
41   perform an ldb search, returning an array of results
42
43   syntax:
44      res = ldb.search(db, "expression");
45      var attrs = new Array("attr1", "attr2", "attr3");
46      ldb.search(db, "expression", attrs);
47 */
48 static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
49 {
50         const char **attrs = NULL;
51         const char *expression;
52         TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
53         struct ldb_context *ldb;
54         int ret;
55         struct ldb_message **res;
56
57         /* validate arguments */
58         if (argc < 2 || argc > 3) {
59                 ejsSetErrorMsg(eid, "ldb.search invalid arguments");
60                 goto failed;
61         }
62         if (argc == 3 && argv[2]->type != MPR_TYPE_OBJECT) {
63                 ejsSetErrorMsg(eid, "ldb.search attributes must be an object");
64                 goto failed;
65         }
66
67         ldb = ejs_ldb_db(eid, argv[0]);
68         if (ldb == NULL) {
69                 return -1;
70         }
71         
72         expression = mprToString(argv[1]);
73         if (expression == NULL) {
74                 ejsSetErrorMsg(eid, "ldb.search invalid arguments");
75                 goto failed;
76         }
77         if (argc > 2) {
78                 attrs = mprToList(tmp_ctx, argv[2]);
79         }
80
81         ret = ldb_search(ldb, NULL, LDB_SCOPE_DEFAULT, expression, attrs, &res);
82         if (ret == -1) {
83                 ejsSetErrorMsg(eid, "ldb.search failed - %s", ldb_errstring(ldb));
84                 mpr_Return(eid, mprCreateUndefinedVar());
85         } else {
86                 mpr_Return(eid, mprLdbArray(res, ret, "ldb_message"));
87         }
88
89         talloc_free(tmp_ctx);
90         return 0;
91
92 failed:
93         talloc_free(tmp_ctx);
94         return -1;
95 }
96
97
98 /*
99   perform an ldb add or modify
100 */
101 static int ejs_ldbAddModify(MprVarHandle eid, int argc, struct MprVar **argv,
102                             int fn(struct ldb_context *, const struct ldb_message *))
103 {
104         const char *ldifstring;
105         struct ldb_context *ldb;
106         struct ldb_ldif *ldif;
107         int ret;
108
109         if (argc != 2) {
110                 ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
111                 return -1;
112         }
113
114         ldifstring = mprToString(argv[1]);
115         if (ldifstring == NULL) {
116                 ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
117                 return -1;
118         }
119
120         ldb = ejs_ldb_db(eid, argv[0]);
121         if (ldb == NULL) {
122                 return -1;
123         }
124
125         while ((ldif = ldb_ldif_read_string(ldb, &ldifstring))) {
126                 ret = fn(ldb, ldif->msg);
127                 talloc_free(ldif);
128                 if (ret != 0) break;
129         }
130
131         mpr_Return(eid, mprCreateBoolVar(ret == 0));
132         return 0;
133 }
134
135
136 /*
137   perform an ldb delete
138   usage:
139    ok = ldb.delete(db, dn);
140 */
141 static int ejs_ldbDelete(MprVarHandle eid, int argc, struct MprVar **argv)
142 {
143         const char *dn;
144         struct ldb_context *ldb;
145         int ret;
146
147         if (argc != 2) {
148                 ejsSetErrorMsg(eid, "ldb.delete invalid arguments");
149                 return -1;
150         }
151
152         dn      = mprToString(argv[1]);
153
154         ldb = ejs_ldb_db(eid, argv[0]);
155         if (ldb == NULL) {
156                 return -1;
157         }
158         ret = ldb_delete(ldb, dn);
159
160         mpr_Return(eid, mprCreateBoolVar(ret == 0));
161         return 0;
162 }
163
164 /*
165   perform an ldb rename
166   usage:
167    ok = ldb.rename(db, dn1, dn2);
168 */
169 static int ejs_ldbRename(MprVarHandle eid, int argc, struct MprVar **argv)
170 {
171         const char *dn1, *dn2;
172         struct ldb_context *ldb;
173         int ret;
174
175         if (argc != 3) {
176                 ejsSetErrorMsg(eid, "ldb.rename invalid arguments");
177                 return -1;
178         }
179
180         dn1    = mprToString(argv[1]);
181         dn2    = mprToString(argv[2]);
182         if (dn1 == NULL || dn2 == NULL) {
183                 ejsSetErrorMsg(eid, "ldb.rename invalid arguments");
184                 return -1;
185         }
186
187         ldb = ejs_ldb_db(eid, argv[0]);
188         if (ldb == NULL) {
189                 return -1;
190         }
191
192         ret = ldb_rename(ldb, dn1, dn2);
193
194         mpr_Return(eid, mprCreateBoolVar(ret == 0));
195         return 0;
196 }
197
198 /*
199   perform an ldb modify
200
201   syntax:
202     ok = ldb.modify(db, ldifstring);
203 */
204 static int ejs_ldbAdd(MprVarHandle eid, int argc, struct MprVar **argv)
205 {
206         return ejs_ldbAddModify(eid, argc, argv, ldb_add);
207 }
208
209 /*
210   perform an ldb add
211
212   syntax:
213     ok = ldb.add(db, ldifstring);
214 */
215 static int ejs_ldbModify(MprVarHandle eid, int argc, struct MprVar **argv)
216 {
217         return ejs_ldbAddModify(eid, argc, argv, ldb_modify);
218 }
219
220 /*
221   connect to a database
222   usage:
223    db = ldb.connect(dbfile);
224 */
225 static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv)
226 {
227         struct ldb_context *ldb;
228         const char *dbfile;
229         struct MprVar v;
230
231         if (argc != 1) {
232                 ejsSetErrorMsg(eid, "ldb.connect invalid arguments");
233                 return -1;
234         }
235
236         dbfile = argv[0];
237
238         ldb = ldb_wrap_connect(mprMemCtx(), dbfile, 0, NULL);
239         if (ldb == NULL) {
240                 ejsSetErrorMsg(eid, "ldb.connect failed to open %s", dbfile);
241                 mpr_Return(eid, mprCreateUndefinedVar());
242         }
243
244         v = mprObject("db");
245         mprSetPtrChild(&v, "ldb", ldb);
246
247         mpr_Return(eid, v);
248         return 0;
249 }
250
251
252 /*
253   initialise ldb ejs subsystem
254 */
255 static int ejs_ldb_init(MprVarHandle eid, int argc, struct MprVar **argv)
256 {
257         struct MprVar ldb = mprObject("ldb");
258
259         mprSetStringCFunction(&ldb, "connect", ejs_ldbConnect);
260         mprSetCFunction(&ldb, "search", ejs_ldbSearch);
261         mprSetCFunction(&ldb, "add", ejs_ldbAdd);
262         mprSetCFunction(&ldb, "modify", ejs_ldbModify);
263         mprSetCFunction(&ldb, "delete", ejs_ldbDelete);
264         mprSetCFunction(&ldb, "rename", ejs_ldbRename);
265
266         mpr_Return(eid, ldb);
267         return 0;
268 }
269
270
271 /*
272   setup C functions that be called from ejs
273 */
274 void smb_setup_ejs_ldb(void)
275 {
276         ejsDefineCFunction(-1, "ldb_init", ejs_ldb_init, NULL, MPR_VAR_SCRIPT_HANDLE);
277 }