Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-gmake3
[kai/samba.git] / source / 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    Copyright (C) Jelmer Vernooij 2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 #include "lib/ldb/include/ldb_errors.h"
28 #include "ldb_wrap.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "librpc/ndr/libndr.h"
31 #include "libcli/security/security.h"
32
33 /*
34   get the connected db
35  */
36 static struct ldb_context *ejs_get_ldb_context(int eid)
37 {
38         struct ldb_context *ldb = (struct ldb_context *)mprGetThisPtr(eid, "db");
39         if (ldb == NULL) {
40                 ejsSetErrorMsg(eid, "invalid ldb connection");
41         }
42         return ldb;
43 }
44
45 /*
46   perform an ldb search, returning an array of results
47
48   syntax:
49      res = ldb.search("expression");
50      var attrs = new Array("attr1", "attr2", "attr3");
51      ldb.search("expression", attrs);
52      var basedn = "cn=this,dc=is,dc=a,dc=test";
53      ldb.search("expression", basedn, ldb.SCOPE_SUBTREE, attrs);
54      ldb.search("expression", basedn, ldb.SCOPE_SUBTREE, attrs, controls);
55 */
56 static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
57 {
58         const char **attrs = NULL;
59         const char *expression;
60         const char *base = NULL;
61         struct ldb_dn *basedn = NULL;
62         int scope = LDB_SCOPE_DEFAULT;
63         TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
64         struct ldb_context *ldb;
65         int ret;
66         struct ldb_control **parsed_controls = NULL;
67         struct ldb_result *res=NULL;
68         struct ldb_request *req;
69
70         /* validate arguments */
71         if (argc < 1 || argc > 5) {
72                 ejsSetErrorMsg(eid, "ldb.search invalid number of arguments");
73                 goto failed;
74         }
75         if (argc > 3 && argv[3]->type != MPR_TYPE_OBJECT) {
76                 ejsSetErrorMsg(eid, "ldb.search attributes must be an object");
77                 goto failed;
78         }
79
80         ldb = ejs_get_ldb_context(eid);
81         if (ldb == NULL) {
82                 return -1;
83         }
84         
85         expression = mprToString(argv[0]);
86         if (argc > 1) {
87                 base = mprToString(argv[1]);
88                 /* a null basedn is valid */
89         }
90         if (base != NULL) {
91                 basedn = ldb_dn_new(tmp_ctx, ldb, base);
92                 if ( ! ldb_dn_validate(basedn)) {
93                         ejsSetErrorMsg(eid, "ldb.search malformed base dn");
94                         goto failed;
95                 }
96         } else {
97                 basedn = ldb_get_default_basedn(ldb);
98         }
99         if (argc > 2) {
100                 scope = mprToInt(argv[2]);
101                 switch (scope) {
102                         case LDB_SCOPE_DEFAULT:
103                         case LDB_SCOPE_BASE:
104                         case LDB_SCOPE_ONELEVEL:
105                         case LDB_SCOPE_SUBTREE:
106                                 break; /* ok */
107                         default:
108                                 ejsSetErrorMsg(eid, "ldb.search invalid scope");
109                                 goto failed;
110                 }
111         }
112         if (argc > 3) {
113                 attrs = mprToList(tmp_ctx, argv[3]);
114         }
115         if (argc > 4) {
116                 const char **controls;
117                 controls = mprToList(tmp_ctx, argv[4]);
118                 if (controls) {
119                         parsed_controls = ldb_parse_control_strings(ldb, tmp_ctx, controls);
120                         if (!parsed_controls) {
121                                 ejsSetErrorMsg(eid, "ldb.search cannot parse controls: %s", 
122                                                ldb_errstring(ldb));
123                                 goto failed;
124                         }
125                 }
126         }
127
128         res = talloc_zero(tmp_ctx, struct ldb_result);
129         if (!res) {
130                 return LDB_ERR_OPERATIONS_ERROR;
131         }
132
133         ret = ldb_build_search_req(&req, ldb, tmp_ctx,
134                                    basedn,
135                                    scope,
136                                    expression,
137                                    attrs,
138                                    parsed_controls,
139                                    res,
140                                    ldb_search_default_callback);
141
142         if (ret == LDB_SUCCESS) {
143
144                 ldb_set_timeout(ldb, req, 0); /* use default timeout */
145                 
146                 ret = ldb_request(ldb, req);
147                 
148                 if (ret == LDB_SUCCESS) {
149                         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
150                 }
151         }
152
153         if (ret != LDB_SUCCESS) {
154                 ejsSetErrorMsg(eid, "ldb.search failed - %s", ldb_errstring(ldb));
155                 mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
156         } else {
157                 mpr_Return(eid, mprLdbResult(ldb, ret, res));
158         }
159
160         talloc_free(tmp_ctx);
161         return 0;
162
163 failed:
164         talloc_free(tmp_ctx);
165         return -1;
166 }
167
168
169 /*
170   perform an ldb add or modify
171 */
172 static int ejs_ldbAddModify(MprVarHandle eid, int argc, struct MprVar **argv,
173                             int fn(struct ldb_context *, const struct ldb_message *))
174 {
175         const char *ldifstring;
176         struct ldb_context *ldb;
177         struct ldb_ldif *ldif;
178         int ret = 0, count=0;
179
180         if (argc != 1) {
181                 ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
182                 return -1;
183         }
184
185         ldifstring = mprToString(argv[0]);
186         if (ldifstring == NULL) {
187                 ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
188                 return -1;
189         }
190
191         ldb = ejs_get_ldb_context(eid);
192         if (ldb == NULL) {
193                 return -1;
194         }
195
196         while ((ldif = ldb_ldif_read_string(ldb, &ldifstring))) {
197                 count++;
198                 ret = fn(ldb, ldif->msg);
199                 talloc_free(ldif);
200                 if (ret != 0) break;
201         }
202
203         if (count == 0) {
204                 ejsSetErrorMsg(eid, "ldb.add/modify invalid ldif");
205                 return -1;
206         }
207
208         mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
209         return 0;
210 }
211
212
213 /*
214   perform an ldb delete
215   usage:
216    ok = ldb.delete(dn);
217 */
218 static int ejs_ldbDelete(MprVarHandle eid, int argc, struct MprVar **argv)
219 {
220         struct ldb_dn *dn;
221         struct ldb_context *ldb;
222         int ret;
223
224         if (argc != 1) {
225                 ejsSetErrorMsg(eid, "ldb.delete invalid arguments");
226                 return -1;
227         }
228
229         ldb = ejs_get_ldb_context(eid);
230         if (ldb == NULL) {
231                 return -1;
232         }
233
234         dn = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
235         if ( ! ldb_dn_validate(dn)) {
236                 ejsSetErrorMsg(eid, "ldb.delete malformed dn");
237                 return -1;
238         }
239
240         ret = ldb_delete(ldb, dn);
241
242         talloc_free(dn);
243
244         mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
245         return 0;
246 }
247
248 /*
249   perform an ldb rename
250   usage:
251    ok = ldb.rename(dn1, dn2);
252 */
253 static int ejs_ldbRename(MprVarHandle eid, int argc, struct MprVar **argv)
254 {
255         struct ldb_dn *dn1, *dn2;
256         struct ldb_context *ldb;
257         int ret;
258
259         if (argc != 2) {
260                 ejsSetErrorMsg(eid, "ldb.rename invalid arguments");
261                 return -1;
262         }
263
264         ldb = ejs_get_ldb_context(eid);
265         if (ldb == NULL) {
266                 return -1;
267         }
268
269         dn1 = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
270         dn2 = ldb_dn_new(ldb, ldb, mprToString(argv[1]));
271         if ( ! ldb_dn_validate(dn1) ||  ! ldb_dn_validate(dn2)) {
272                 ejsSetErrorMsg(eid, "ldb.rename invalid or malformed arguments");
273                 return -1;
274         }
275
276         ret = ldb_rename(ldb, dn1, dn2);
277
278         talloc_free(dn1);
279         talloc_free(dn2);
280
281         mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
282         return 0;
283 }
284
285 /*
286   get last error message
287   usage:
288    ok = ldb.errstring();
289 */
290 static int ejs_ldbErrstring(MprVarHandle eid, int argc, struct MprVar **argv)
291 {
292         struct ldb_context *ldb;
293
294         ldb = ejs_get_ldb_context(eid);
295         if (ldb == NULL) {
296                 return -1;
297         }
298
299         mpr_Return(eid, mprString(ldb_errstring(ldb)));
300         return 0;
301 }
302
303 /* 
304    base64 encode 
305    usage: 
306     dataout = ldb.encode(datain)
307  */
308 static int ejs_base64encode(MprVarHandle eid, int argc, struct MprVar **argv)
309 {
310         char *ret;
311
312         if (argc != 1) {
313                 ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
314                 return -1;
315         }
316
317         if (argv[0]->type == MPR_TYPE_STRING) {
318                 const char *orig = mprToString(argv[0]);
319                 ret = ldb_base64_encode(mprMemCtx(), orig, strlen(orig));
320         } else {
321                 DATA_BLOB *blob;
322
323                 blob = mprToDataBlob(argv[0]);
324                 mprAssert(blob);
325                 ret = ldb_base64_encode(mprMemCtx(), (char *)blob->data, blob->length);
326         }
327                 
328         if (!ret) {
329                 mpr_Return(eid, mprCreateUndefinedVar());
330         } else {
331                 mpr_Return(eid, mprString(ret));
332         }
333
334         talloc_free(ret);
335
336         return 0;
337 }
338
339 /* 
340    base64 decode
341    usage:
342      dataout = ldb.decode(datain)
343  */
344 static int ejs_base64decode(MprVarHandle eid, int argc, struct MprVar **argv)
345 {
346         char *tmp;
347         int ret;
348         
349         if (argc != 1) {
350                 ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
351                 return -1;
352         }
353
354         tmp = talloc_strdup(mprMemCtx(), mprToString(argv[0]));
355         ret = ldb_base64_decode(tmp);
356         if (ret == -1) {
357                 mpr_Return(eid, mprCreateUndefinedVar());
358         } else {
359                 DATA_BLOB blob;
360                 blob.data = (uint8_t *)tmp;
361                 blob.length = ret;
362                 mpr_Return(eid, mprDataBlob(blob));
363         }
364
365         talloc_free(tmp);
366
367         return 0;
368 }
369
370 /* 
371    escape a DN
372    usage:
373      dataout = ldb.dn_escape(datain)
374  */
375 static int ejs_dn_escape(MprVarHandle eid, int argc, struct MprVar **argv)
376 {
377         char *ret;
378         struct ldb_val val;
379         
380         if (argc != 1) {
381                 ejsSetErrorMsg(eid, "ldb.dn_escape invalid argument count");
382                 return -1;
383         }
384
385         val = data_blob_string_const(mprToString(argv[0]));
386
387         ret = ldb_dn_escape_value(mprMemCtx(), val);
388         if (ret == NULL) {
389                 mpr_Return(eid, mprCreateUndefinedVar());
390         } else {
391                 mpr_Return(eid, mprString(ret));
392                 talloc_free(ret);
393         }
394
395         return 0;
396 }
397
398 /*
399   perform an ldb add 
400
401   syntax:
402     ok = ldb.add(ldifstring);
403 */
404 static int ejs_ldbAdd(MprVarHandle eid, int argc, struct MprVar **argv)
405 {
406         return ejs_ldbAddModify(eid, argc, argv, ldb_add);
407 }
408
409 /*
410   perform an ldb modify
411
412   syntax:
413     ok = ldb.modify(ldifstring);
414 */
415 static int ejs_ldbModify(MprVarHandle eid, int argc, struct MprVar **argv)
416 {
417         return ejs_ldbAddModify(eid, argc, argv, ldb_modify);
418 }
419
420 /*
421   connect to a database
422   usage:
423    ok = ldb.connect(dbfile);
424    ok = ldb.connect(dbfile, "modules:modlist");
425
426   ldb.credentials or ldb.session_info may be setup first
427
428 */
429 static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv)
430 {
431         struct ldb_context *ldb;
432         struct auth_session_info *session_info = NULL;
433         struct cli_credentials *creds = NULL;
434         struct MprVar *credentials, *session;
435         struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
436
437         const char *dbfile;
438
439         if (argc < 1) {
440                 ejsSetErrorMsg(eid, "ldb.connect invalid arguments");
441                 return -1;
442         }
443
444         credentials = mprGetProperty(this, "credentials", NULL);
445         if (credentials) {
446                 creds = talloc_get_type(mprGetPtr(credentials, "creds"), struct cli_credentials);
447         }
448
449         session = mprGetProperty(this, "session_info", NULL);
450         if (session) {
451                 session_info = talloc_get_type(mprGetPtr(session, "session_info"), struct auth_session_info);
452         }
453
454         dbfile = argv[0];
455
456         ldb = ldb_wrap_connect(mprMemCtx(), mprEventCtx(), mprLpCtx(), dbfile, 
457                                session_info, creds,
458                                0, (const char **)(argv+1));
459         if (ldb == NULL) {
460                 ejsSetErrorMsg(eid, "ldb.connect failed to open %s", dbfile);
461         }
462
463         mprSetThisPtr(eid, "db", ldb);
464         mpr_Return(eid, mprCreateBoolVar(ldb != NULL));
465         return 0;
466 }
467
468
469 /*
470   close a db connection
471 */
472 static int ejs_ldbClose(MprVarHandle eid, int argc, struct MprVar **argv)
473 {
474         struct ldb_context *ldb;
475
476         if (argc != 0) {
477                 ejsSetErrorMsg(eid, "ldb.close invalid arguments");
478                 return -1;
479         }
480
481         ldb = ejs_get_ldb_context(eid);
482         if (ldb == NULL) {
483                 return -1;
484         }
485
486         mprSetThisPtr(eid, "db", NULL);
487         mpr_Return(eid, mprCreateBoolVar(true));
488         return 0;
489 }
490
491
492 /*
493   start a ldb transaction
494   usage:
495    ok = ldb.transaction_start();
496 */
497 static int ejs_ldbTransactionStart(MprVarHandle eid, int argc, struct MprVar **argv)
498 {
499         struct ldb_context *ldb;
500         int ret;
501
502         if (argc != 0) {
503                 ejsSetErrorMsg(eid, "ldb.transaction_start invalid arguments");
504                 return -1;
505         }
506
507         ldb = ejs_get_ldb_context(eid);
508         if (ldb == NULL) {
509                 return -1;
510         }
511
512         ret = ldb_transaction_start(ldb);
513
514         mpr_Return(eid, mprCreateBoolVar(ret == 0));
515         return 0;
516 }
517
518 /*
519   cancel a ldb transaction
520   usage:
521    ok = ldb.transaction_cancel();
522 */
523 static int ejs_ldbTransactionCancel(MprVarHandle eid, int argc, struct MprVar **argv)
524 {
525         struct ldb_context *ldb;
526         int ret;
527
528         if (argc != 0) {
529                 ejsSetErrorMsg(eid, "ldb.transaction_cancel invalid arguments");
530                 return -1;
531         }
532
533         ldb = ejs_get_ldb_context(eid);
534         if (ldb == NULL) {
535                 return -1;
536         }
537
538         ret = ldb_transaction_cancel(ldb);
539
540         mpr_Return(eid, mprCreateBoolVar(ret == 0));
541         return 0;
542 }
543
544 /*
545   commit a ldb transaction
546   usage:
547    ok = ldb.transaction_commit();
548 */
549 static int ejs_ldbTransactionCommit(MprVarHandle eid, int argc, struct MprVar **argv)
550 {
551         struct ldb_context *ldb;
552         int ret;
553
554         if (argc != 0) {
555                 ejsSetErrorMsg(eid, "ldb.transaction_commit invalid arguments");
556                 return -1;
557         }
558
559         ldb = ejs_get_ldb_context(eid);
560         if (ldb == NULL) {
561                 return -1;
562         }
563
564         ret = ldb_transaction_commit(ldb);
565
566         mpr_Return(eid, mprCreateBoolVar(ret == 0));
567         return 0;
568 }
569
570 /*
571   commit a ldb attach a dsdb_schema from ldif files
572   usage:
573    ok = ldb.attach_dsdb_schema_from_ldif("prefixMap ldif content", "definition ldif content")
574 */
575 static int ejs_ldb_attach_dsdb_schema_from_ldif(MprVarHandle eid, int argc, char **argv)
576 {
577         struct ldb_context *ldb;
578         WERROR status;
579         const char *pf;
580         const char *df;
581
582         if (argc != 2) {
583                 ejsSetErrorMsg(eid, "ldb.attach_dsdb_schema_from_ldif invalid arguments");
584                 return -1;
585         }
586
587         ldb = ejs_get_ldb_context(eid);
588         if (ldb == NULL) {
589                 return -1;
590         }
591
592         pf = argv[0];
593         df = argv[1];
594
595         status = dsdb_attach_schema_from_ldif_file(ldb, pf, df);
596
597         mpr_Return(eid, mprWERROR(status));
598         return 0;
599 }
600
601 /*
602   set a particular invocationId against the running LDB
603   usage:
604    ok = ldb.set_ntds_invocationId("7729aa4b-f990-41ad-b81a-8b6a14090f41");
605 */
606 static int ejs_ldb_set_ntds_invocationId(MprVarHandle eid, int argc, char **argv)
607 {
608         struct ldb_context *ldb;
609         NTSTATUS status;
610         struct GUID guid;
611         char *guid_str;
612         bool ok;
613
614         if (argc != 1) {
615                 ejsSetErrorMsg(eid, "ldb.set_ntds_invocationId invalid arguments");
616                 return -1;
617         }
618
619         ldb = ejs_get_ldb_context(eid);
620         if (ldb == NULL) {
621                 return -1;
622         }
623
624         guid_str = argv[0];
625
626         status = GUID_from_string(guid_str, &guid);
627         if (!NT_STATUS_IS_OK(status)) {
628                 ejsSetErrorMsg(eid, "ldb.set_ntds_invocationId - failed to parse GUID '%s' %s\n",
629                                 guid_str, nt_errstr(status));
630                 return -1;
631         }
632
633         ok = samdb_set_ntds_invocation_id(ldb, &guid);
634         if (!ok) {
635                 ejsSetErrorMsg(eid, "ldb.set_ntds_invocationId - failed to set cached ntds invocationId\n");
636                 return -1;
637         }
638
639         mpr_Return(eid, mprCreateBoolVar(ok));
640         return 0;
641 }
642
643 /*
644   attach a particular ntds objectGUID against the current ldb
645   usage:
646    ok = ldb.set_ntds_objectGUID("7729aa4b-f990-41ad-b81a-8b6a14090f41");
647 */
648 static int ejs_ldb_set_ntds_objectGUID(MprVarHandle eid, int argc, char **argv)
649 {
650         struct ldb_context *ldb;
651         NTSTATUS status;
652         struct GUID guid;
653         char *guid_str;
654         bool ok;
655
656         if (argc != 1) {
657                 ejsSetErrorMsg(eid, "ldb.set_ntds_objectGUID invalid arguments");
658                 return -1;
659         }
660
661         ldb = ejs_get_ldb_context(eid);
662         if (ldb == NULL) {
663                 return -1;
664         }
665
666         guid_str = argv[0];
667
668         status = GUID_from_string(guid_str, &guid);
669         if (!NT_STATUS_IS_OK(status)) {
670                 ejsSetErrorMsg(eid, "ldb.set_ntds_objectGUID - failed to parse GUID '%s' %s\n",
671                                 guid_str, nt_errstr(status));
672                 return -1;
673         }
674
675         ok = samdb_set_ntds_invocation_id(ldb, &guid);
676         if (!ok) {
677                 ejsSetErrorMsg(eid, "ldb.set_ntds_objectGUID - failed to set cached ntds invocationId\n");
678                 return -1;
679         }
680
681         mpr_Return(eid, mprCreateBoolVar(ok));
682         return 0;
683 }
684
685 /*
686   attach a particular domain SID against the current ldb
687   usage:
688    ok = ldb.set_domain_sid("S-S-1-5-21-3065342217-3567412576-2214182334");
689 */
690 static int ejs_ldb_set_domain_sid(MprVarHandle eid, int argc, char **argv)
691 {
692         struct ldb_context *ldb;
693         struct dom_sid *dom_sid;
694         char *dom_sid_str;
695         bool ok;
696
697         if (argc != 1) {
698                 ejsSetErrorMsg(eid, "ldb.set_domain_sid invalid arguments");
699                 return -1;
700         }
701
702         ldb = ejs_get_ldb_context(eid);
703         if (ldb == NULL) {
704                 return -1;
705         }
706
707         dom_sid_str = argv[0];
708
709         dom_sid = dom_sid_parse_talloc(NULL, dom_sid_str);
710         if (!dom_sid) {
711                 ejsSetErrorMsg(eid, "ldb.set_domain_sid - failed to parse domain sid '%s'\n",
712                                 dom_sid_str);
713                 return -1;
714         }
715
716         ok = samdb_set_domain_sid(ldb, dom_sid);
717         talloc_free(dom_sid);
718         if (!ok) {
719                 ejsSetErrorMsg(eid, "ldb.set_domain_sid - failed to set cached ntds invocationId\n");
720                 return -1;
721         }
722
723         mpr_Return(eid, mprCreateBoolVar(ok));
724         return 0;
725 }
726
727 /*
728   initialise ldb ejs subsystem
729 */
730 static int ejs_ldb_init(MprVarHandle eid, int argc, struct MprVar **argv)
731 {
732         struct MprVar *ldb = mprInitObject(eid, "ldb", argc, argv);
733
734         mprSetStringCFunction(ldb, "connect", ejs_ldbConnect);
735         mprSetCFunction(ldb, "search", ejs_ldbSearch);
736         mprSetCFunction(ldb, "add", ejs_ldbAdd);
737         mprSetCFunction(ldb, "modify", ejs_ldbModify);
738         mprSetCFunction(ldb, "del", ejs_ldbDelete);
739         mprSetCFunction(ldb, "rename", ejs_ldbRename);
740         mprSetCFunction(ldb, "errstring", ejs_ldbErrstring);
741         mprSetCFunction(ldb, "encode", ejs_base64encode);
742         mprSetCFunction(ldb, "decode", ejs_base64decode);
743         mprSetCFunction(ldb, "dn_escape", ejs_dn_escape);
744         mprSetCFunction(ldb, "close", ejs_ldbClose);
745         mprSetCFunction(ldb, "transaction_start", ejs_ldbTransactionStart);
746         mprSetCFunction(ldb, "transaction_cancel", ejs_ldbTransactionCancel);
747         mprSetCFunction(ldb, "transaction_commit", ejs_ldbTransactionCommit);
748         mprSetStringCFunction(ldb, "attach_dsdb_schema_from_ldif",
749                               ejs_ldb_attach_dsdb_schema_from_ldif);
750         mprSetStringCFunction(ldb, "set_ntds_invocationId",
751                               ejs_ldb_set_ntds_invocationId);
752         mprSetStringCFunction(ldb, "set_ntds_objectGUID",
753                               ejs_ldb_set_ntds_objectGUID);
754         mprSetStringCFunction(ldb, "set_domain_sid",
755                               ejs_ldb_set_domain_sid);
756         mprSetVar(ldb, "SCOPE_BASE", mprCreateNumberVar(LDB_SCOPE_BASE));
757         mprSetVar(ldb, "SCOPE_ONE", mprCreateNumberVar(LDB_SCOPE_ONELEVEL));
758         mprSetVar(ldb, "SCOPE_SUBTREE", mprCreateNumberVar(LDB_SCOPE_SUBTREE));
759         mprSetVar(ldb, "SCOPE_DEFAULT", mprCreateNumberVar(LDB_SCOPE_DEFAULT));
760
761         return 0;
762 }
763
764
765 /*
766   setup C functions that be called from ejs
767 */
768 NTSTATUS smb_setup_ejs_ldb(void)
769 {
770         ejsDefineCFunction(-1, "ldb_init", ejs_ldb_init, NULL, MPR_VAR_SCRIPT_HANDLE);
771         return NT_STATUS_OK;
772 }