0a05e4584fdd5f5c76d6bdd58955ddb352d0426f
[kai/samba.git] / source4 / scripting / ejs / smbcalls_samba3.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    provide hooks into smbd C calls from ejs scripts
5
6    Copyright (C) Jelmer Vernooij 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/samba3/samba3.h"
27
28
29 static struct MprVar mprRegistry(struct samba3_regdb *reg)
30 {
31         struct MprVar mpv = mprObject("registry"), ks, vs, k, v;
32         int i, j;
33
34         ks = mprArray("array");
35
36         for (i = 0; i < reg->key_count; i++) {
37                 k = mprObject("regkey");
38
39                 mprSetVar(&k, "name", mprString(reg->keys[i].name));
40
41                 vs = mprArray("array");
42                 
43                 for (j = 0; j < reg->keys[i].value_count; j++) {
44                         v = mprObject("regval");
45
46                         mprSetVar(&v, "name", mprString(reg->keys[i].values[j].name));
47                         mprSetVar(&v, "type", mprCreateIntegerVar(reg->keys[i].values[j].type));
48                         mprSetVar(&v, "data", mprDataBlob(reg->keys[i].values[j].data));
49
50                         mprAddArray(&vs, j, v);
51                 }
52
53                 mprSetVar(&k, "values", vs);
54
55                 mprAddArray(&ks, i, k);
56         }
57
58         if (i == 0) {
59                 mprSetVar(&ks, "length", mprCreateIntegerVar(i));
60         }
61
62         mprSetVar(&mpv, "keys", ks);
63
64         return mpv;
65 }
66
67 static struct MprVar mprPolicy(struct samba3_policy *pol)
68 {
69         struct MprVar mpv = mprObject("policy");
70
71         mprSetVar(&mpv, "min_password_length", mprCreateIntegerVar(pol->min_password_length));
72         mprSetVar(&mpv, "password_history", mprCreateIntegerVar(pol->password_history));
73         mprSetVar(&mpv, "user_must_logon_to_change_password", mprCreateIntegerVar(pol->user_must_logon_to_change_password));
74         mprSetVar(&mpv, "maximum_password_age", mprCreateIntegerVar(pol->maximum_password_age));
75         mprSetVar(&mpv, "minimum_password_age", mprCreateIntegerVar(pol->minimum_password_age));
76         mprSetVar(&mpv, "lockout_duration", mprCreateIntegerVar(pol->lockout_duration));
77         mprSetVar(&mpv, "reset_count_minutes", mprCreateIntegerVar(pol->reset_count_minutes));
78         mprSetVar(&mpv, "bad_lockout_minutes", mprCreateIntegerVar(pol->bad_lockout_minutes));
79         mprSetVar(&mpv, "disconnect_time", mprCreateIntegerVar(pol->disconnect_time));
80         mprSetVar(&mpv, "refuse_machine_password_change", mprCreateIntegerVar(pol->refuse_machine_password_change));
81
82         return mpv;
83 }
84
85 static struct MprVar mprIdmapDb(struct samba3_idmapdb *db)
86 {
87         struct MprVar mpv = mprObject("idmapdb"), mps, mp;
88         int i;
89
90         mprSetVar(&mpv, "user_hwm", mprCreateIntegerVar(db->user_hwm));
91         mprSetVar(&mpv, "group_hwm", mprCreateIntegerVar(db->group_hwm));
92
93         mps = mprArray("array");
94
95         for (i = 0; i < db->mapping_count; i++) {
96                 char *tmp;
97                 mp = mprObject("idmap");
98
99                 mprSetVar(&mp, "IDMAP_GROUP", mprCreateIntegerVar(IDMAP_GROUP));
100                 mprSetVar(&mp, "IDMAP_USER", mprCreateIntegerVar(IDMAP_USER));
101                 mprSetVar(&mp, "type", mprCreateIntegerVar(db->mappings[i].type));
102                 mprSetVar(&mp, "unix_id", mprCreateIntegerVar(db->mappings[i].unix_id));
103
104                 tmp = dom_sid_string(NULL, db->mappings[i].sid);
105                 mprSetVar(&mp, "sid", mprString(tmp));
106                 talloc_free(tmp);
107
108                 mprAddArray(&mps, i, mp);
109         }
110
111         if (i == 0) {
112                 mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
113         }
114
115
116         mprSetVar(&mpv, "mappings", mps);
117
118         return mpv;
119 }
120
121 static struct MprVar mprGroupMappings(struct samba3_groupdb *db)
122 {
123         struct MprVar mpv = mprArray("array"), g;
124         int i;
125
126         for (i = 0; i < db->groupmap_count; i++) {
127                 char *tmp;
128                 g = mprObject("group");
129
130                 mprSetVar(&g, "gid", mprCreateIntegerVar(db->groupmappings[i].gid));
131
132                 tmp = dom_sid_string(NULL, db->groupmappings[i].sid);
133                 mprSetVar(&g, "sid", mprString(tmp));
134                 talloc_free(tmp);
135
136                 mprSetVar(&g, "sid_name_use", mprCreateIntegerVar(db->groupmappings[i].sid_name_use));
137                 mprSetVar(&g, "nt_name", mprString(db->groupmappings[i].nt_name));
138                 mprSetVar(&g, "comment", mprString(db->groupmappings[i].comment));
139
140                 mprAddArray(&mpv, i, g);
141         }
142
143         if (i == 0) {
144                 mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
145         }
146
147
148         return mpv;
149 }
150
151 static struct MprVar mprAliases(struct samba3_groupdb *db)
152 {
153         struct MprVar mpv = mprObject("array"), a, am;
154         int i, j;
155
156         for (i = 0; i < db->alias_count; i++) {
157                 char *tmp;
158                 a = mprObject("alias");
159
160                 tmp = dom_sid_string(NULL, db->aliases[i].sid);
161                 mprSetVar(&a, "sid", mprString(tmp));
162                 talloc_free(tmp);
163
164                 am = mprArray("array");
165
166                 for (j = 0; j < db->aliases[i].member_count; j++) {
167                         tmp = dom_sid_string(NULL, db->aliases[i].members[j]);
168                         mprAddArray(&am, j, mprString(tmp));
169                         talloc_free(tmp);
170                 }
171
172                 mprSetVar(&a, "members", am);
173         }
174
175         if (i == 0) {
176                 mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
177         }
178
179         return mpv;
180 }
181
182 static struct MprVar mprDomainSecrets(struct samba3_domainsecrets *ds)
183 {
184         struct MprVar v, e = mprObject("domainsecrets");
185         char *tmp;
186         DATA_BLOB blob;
187
188         mprSetVar(&e, "name", mprString(ds->name));
189
190         tmp = dom_sid_string(NULL, &ds->sid);
191         mprSetVar(&e, "sid", mprString(tmp));
192         talloc_free(tmp);
193
194         tmp = GUID_string(NULL, &ds->guid);
195         mprSetVar(&e, "guid", mprString(tmp));
196         talloc_free(tmp);
197
198         mprSetVar(&e, "plaintext_pw", mprString(ds->plaintext_pw));
199
200         mprSetVar(&e, "last_change_time", mprCreateIntegerVar(ds->last_change_time));
201         mprSetVar(&e, "sec_channel_type", mprCreateIntegerVar(ds->sec_channel_type));
202
203         v = mprObject("hash_pw");
204
205         blob.data = ds->hash_pw.hash;
206         blob.length = 16;
207         mprSetVar(&v, "hash", mprDataBlob(blob));
208
209         mprSetVar(&v, "mod_time", mprCreateIntegerVar(ds->hash_pw.mod_time));
210
211         mprSetVar(&e, "hash_pw", v);
212
213         return e;
214 }
215
216 static struct MprVar mprSecrets(struct samba3_secrets *sec)
217 {
218         struct MprVar mpv = mprObject("samba3_secrets"), es, e;
219         int i;
220
221         es = mprArray("array");
222
223         for (i = 0; i < sec->ldappw_count; i++) {
224                 e = mprObject("ldappw");
225
226                 mprSetVar(&e, "dn", mprString(sec->ldappws[i].dn));
227                 mprSetVar(&e, "password", mprString(sec->ldappws[i].password));
228
229                 mprAddArray(&es, i, e);
230         }
231
232         mprSetVar(&mpv, "ldappws", es);
233
234         es = mprArray("array");
235
236         for (i = 0; i < sec->domain_count; i++) {
237                 mprAddArray(&es, i, mprDomainSecrets(&sec->domains[i]));
238         }
239
240         if (i == 0) {
241                 mprSetVar(&es, "length", mprCreateIntegerVar(i));
242         }
243
244         mprSetVar(&mpv, "domains", es);
245
246         es = mprArray("trusted_domains");
247
248         for (i = 0; i < sec->trusted_domain_count; i++) {
249                 struct MprVar ns;
250                 char *tmp;
251                 int j;
252                 e = mprObject("trusted_domain");
253
254                 ns = mprArray("array");
255
256                 for (j = 0; j < sec->trusted_domains[i].uni_name_len; j++) {
257                         mprAddArray(&ns, j, mprString(sec->trusted_domains[i].uni_name[j]));
258                 }
259
260                 mprSetVar(&e, "uni_name", ns);
261
262                 mprSetVar(&e, "pass", mprString(sec->trusted_domains[i].pass));
263                 mprSetVar(&e, "mod_time", mprCreateIntegerVar(sec->trusted_domains[i].mod_time));
264
265                 tmp = dom_sid_string(NULL, &sec->trusted_domains[i].domain_sid);
266                 mprSetVar(&e, "domains_sid", mprString(tmp));
267                 talloc_free(tmp);
268
269                 mprAddArray(&es, i, e);
270         }
271
272         if (i == 0) {
273                 mprSetVar(&es, "length", mprCreateIntegerVar(i));
274         }
275
276         mprSetVar(&mpv, "trusted_domains", es);
277         
278         es = mprArray("array");
279
280         for (i = 0; i < sec->afs_keyfile_count; i++) {
281                 struct MprVar ks;
282                 int j;
283                 e = mprObject("afs_keyfile");
284
285                 mprSetVar(&e, "cell", mprString(sec->afs_keyfiles[i].cell));
286
287                 ks = mprArray("array");
288                 
289                 for (j = 0; j < 8; j++) {
290                         struct MprVar k = mprObject("entry");
291                         DATA_BLOB blob;
292                         
293                         mprSetVar(&k, "kvno", mprCreateIntegerVar(sec->afs_keyfiles[i].entry[j].kvno));
294                         blob.data = (uint8_t*)sec->afs_keyfiles[i].entry[j].key;
295                         blob.length = 8;
296                         mprSetVar(&k, "key", mprDataBlob(blob));
297
298                         mprAddArray(&ks, j, k);
299                 }
300
301                 mprSetVar(&e, "entry", ks);
302
303                 mprSetVar(&e, "nkeys", mprCreateIntegerVar(sec->afs_keyfiles[i].nkeys));
304
305                 mprAddArray(&es, i, e);
306         }
307
308         if (i == 0) {
309                 mprSetVar(&es, "length", mprCreateIntegerVar(i));
310         }
311
312         mprSetVar(&mpv, "afs_keyfiles", es);
313
314         mprSetVar(&mpv, "ipc_cred", mprCredentials(sec->ipc_cred));
315
316         return mpv;
317 }
318
319 static struct MprVar mprShares(struct samba3 *samba3)
320 {
321         struct MprVar mpv = mprArray("array"), s;
322         int i;
323
324         for (i = 0; i < samba3->share_count; i++) {
325                 s = mprObject("share");
326
327                 mprSetVar(&s, "name", mprString(samba3->shares[i].name));
328
329                 /* FIXME: secdesc */
330
331                 mprAddArray(&mpv, i, s);
332         }
333
334         if (i == 0) {
335                 mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
336         }
337
338         return mpv;
339 }
340
341 static struct MprVar mprSamAccounts(struct samba3 *samba3)
342 {
343         struct MprVar mpv = mprArray("array"), m;
344         int i;
345
346         for (i = 0; i < samba3->samaccount_count; i++) {
347                 struct samba3_samaccount *a = &samba3->samaccounts[i];
348                 DATA_BLOB blob;
349
350                 m = mprObject("samba3_samaccount");
351
352                 mprSetVar(&m, "logon_time", mprCreateIntegerVar(a->logon_time));
353                 mprSetVar(&m, "logoff_time", mprCreateIntegerVar(a->logoff_time));
354                 mprSetVar(&m, "kickoff_time", mprCreateIntegerVar(a->kickoff_time));
355                 mprSetVar(&m, "bad_password_time", mprCreateIntegerVar(a->bad_password_time));
356                 mprSetVar(&m, "pass_last_set_time", mprCreateIntegerVar(a->pass_last_set_time));
357                 mprSetVar(&m, "pass_can_change_time", mprCreateIntegerVar(a->pass_can_change_time));
358                 mprSetVar(&m, "pass_must_change_time", mprCreateIntegerVar(a->pass_must_change_time));
359                 mprSetVar(&m, "user_rid", mprCreateIntegerVar(a->user_rid));
360                 mprSetVar(&m, "group_rid", mprCreateIntegerVar(a->group_rid));
361                 mprSetVar(&m, "acct_ctrl", mprCreateIntegerVar(a->acct_ctrl));
362                 mprSetVar(&m, "logon_divs", mprCreateIntegerVar(a->logon_divs));
363                 mprSetVar(&m, "bad_password_count", mprCreateIntegerVar(a->bad_password_count));
364                 mprSetVar(&m, "logon_count", mprCreateIntegerVar(a->logon_count));
365                 mprSetVar(&m, "username", mprString(a->username));
366                 mprSetVar(&m, "domain", mprString(a->domain));
367                 mprSetVar(&m, "nt_username", mprString(a->nt_username));
368                 mprSetVar(&m, "dir_drive", mprString(a->dir_drive));
369                 mprSetVar(&m, "munged_dial", mprString(a->munged_dial));
370                 mprSetVar(&m, "fullname", mprString(a->fullname));
371                 mprSetVar(&m, "homedir", mprString(a->homedir));
372                 mprSetVar(&m, "logon_script", mprString(a->logon_script));
373                 mprSetVar(&m, "profile_path", mprString(a->profile_path));
374                 mprSetVar(&m, "acct_desc", mprString(a->acct_desc));
375                 mprSetVar(&m, "workstations", mprString(a->workstations));
376                 blob.length = 16;
377                 blob.data = a->lm_pw.hash;
378                 mprSetVar(&m, "lm_pw", mprDataBlob(blob));
379                 blob.data = a->nt_pw.hash;
380                 mprSetVar(&m, "nt_pw", mprDataBlob(blob));
381
382                 mprAddArray(&mpv, i, m);
383         }
384
385         if (i == 0) {
386                 mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
387         }
388
389         return mpv;
390 }
391
392 static struct MprVar mprWinsEntries(struct samba3 *samba3)
393 {
394         struct MprVar mpv = mprArray("array");
395         int i, j;
396
397         for (i = 0; i < samba3->winsdb_count; i++) {
398                 struct MprVar w = mprObject("wins_entry"), ips;
399
400                 mprSetVar(&w, "name", mprString(samba3->winsdb_entries[i].name));
401                 mprSetVar(&w, "nb_flags", mprCreateIntegerVar(samba3->winsdb_entries[i].nb_flags));
402                 mprSetVar(&w, "type", mprCreateIntegerVar(samba3->winsdb_entries[i].type));
403                 mprSetVar(&w, "ttl", mprCreateIntegerVar(samba3->winsdb_entries[i].ttl));
404
405                 ips = mprObject("array");
406
407                 for (j = 0; j < samba3->winsdb_entries[i].ip_count; j++) {
408                         const char *addr;
409                         addr = sys_inet_ntoa(samba3->winsdb_entries[i].ips[j]);
410                         mprAddArray(&ips, j, mprString(addr));
411                 }
412
413                 mprSetVar(&w, "ips", ips);
414                 
415                 mprAddArray(&mpv, i, w);
416         }
417
418         if (i == 0) {
419                 mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
420         }
421
422         return mpv;
423 }
424
425 static int ejs_find_domainsecrets(MprVarHandle eid, int argc, struct MprVar **argv)
426 {
427         struct samba3 *samba3 = NULL;
428         struct samba3_domainsecrets *sec;
429
430         if (argc < 1) {
431                 ejsSetErrorMsg(eid, "find_domainsecrets invalid arguments");
432                 return -1;
433         }
434
435         samba3 = mprGetThisPtr(eid, "samba3");
436         mprAssert(samba3);
437         sec = samba3_find_domainsecrets(samba3, mprToString(argv[0]));
438
439         if (sec == NULL) {
440                 mpr_Return(eid, mprCreateUndefinedVar());
441         } else {
442                 mpr_Return(eid, mprDomainSecrets(sec));
443         }
444
445         return 0;
446 }
447
448 /*
449   initialise samba3 ejs subsystem
450
451   samba3 = samba3_read(libdir,smbconf)
452 */
453 static int ejs_samba3_read(MprVarHandle eid, int argc, struct MprVar **argv)
454 {
455         struct MprVar mpv = mprObject("samba3");
456         struct samba3 *samba3;
457         NTSTATUS status;
458
459         if (argc < 2) {
460                 ejsSetErrorMsg(eid, "samba3_read invalid arguments");
461                 return -1;
462         }
463
464         status = samba3_read(mprToString(argv[0]), mprToString(argv[1]), mprMemCtx(), &samba3);
465
466         if (NT_STATUS_IS_ERR(status)) {
467                 ejsSetErrorMsg(eid, "samba3_read: error");
468                 return -1;
469         }
470
471         mprAssert(samba3);
472         
473         mprSetPtrChild(&mpv, "samba3", samba3);
474         mprSetVar(&mpv, "winsentries", mprWinsEntries(samba3));
475         mprSetVar(&mpv, "samaccounts", mprSamAccounts(samba3));
476         mprSetVar(&mpv, "shares", mprShares(samba3));
477         mprSetVar(&mpv, "secrets", mprSecrets(&samba3->secrets));
478         mprSetVar(&mpv, "groupmappings", mprGroupMappings(&samba3->group));
479         mprSetVar(&mpv, "aliases", mprAliases(&samba3->group));
480         mprSetVar(&mpv, "idmapdb", mprIdmapDb(&samba3->idmap));
481         mprSetVar(&mpv, "policy", mprPolicy(&samba3->policy));
482         mprSetVar(&mpv, "registry", mprRegistry(&samba3->registry));
483         mprSetVar(&mpv, "configuration", mprParam(samba3->configuration));
484         mprSetCFunction(&mpv, "find_domainsecrets", ejs_find_domainsecrets);
485
486         mpr_Return(eid, mpv);
487         
488         return 0;
489 }
490
491
492 /*
493   setup C functions that be called from ejs
494 */
495 void smb_setup_ejs_samba3(void)
496 {
497         ejsDefineCFunction(-1, "samba3_read", ejs_samba3_read, NULL, MPR_VAR_SCRIPT_HANDLE);
498 }