r20143: a bit of experiments before doing serious changes in ejsnet.
[ira/wip.git] / source / scripting / ejs / ejsnet.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    provide interfaces to libnet calls from ejs scripts
5
6    Copyright (C) Rafal Szczesniak  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 "lib/appweb/ejs/ejs.h"
25 #include "scripting/ejs/smbcalls.h"
26 #include "scripting/ejs/ejsnet.h"
27 #include "libnet/libnet.h"
28 #include "events/events.h"
29 #include "auth/credentials/credentials.h"
30
31 static int ejs_net_userman(MprVarHandle eid, int argc, struct MprVar** argv);
32 static int ejs_net_createuser(MprVarHandle eid, int argc, char **argv);
33 static int ejs_net_deleteuser(MprVarHandle eid, int argc, char **argv);
34 static int ejs_net_userinfo(MprVarHandle eid, int argc, char **argv);
35 static int ejs_net_join_domain(MprVarHandle eid, int argc, struct MprVar **argv);
36 static int ejs_net_samsync_ldb(MprVarHandle eid, int argc, struct MprVar **argv);
37
38 /*
39   Usage:
40   net = NetContext(credentials);
41 */
42
43 static int ejs_net_context(MprVarHandle eid, int argc, struct MprVar **argv)
44 {
45         TALLOC_CTX *event_mem_ctx = talloc_new(mprMemCtx());
46         struct cli_credentials *creds;
47         struct libnet_context *ctx;
48         struct MprVar obj;
49         struct event_context *ev;
50
51         if (!event_mem_ctx) {
52                 ejsSetErrorMsg(eid, "talloc_new() failed");
53                 return -1;
54         }
55         ev = event_context_find(event_mem_ctx);
56         ctx = libnet_context_init(ev);
57         /* IF we generated a new event context, it will be under here,
58          * and we need it to last as long as the libnet context, so
59          * make it a child */
60         talloc_steal(ctx, event_mem_ctx);
61
62         if (argc == 0 || (argc == 1 && argv[0]->type == MPR_TYPE_NULL)) {
63                 creds = cli_credentials_init(ctx);
64                 if (creds == NULL) {
65                         ejsSetErrorMsg(eid, "cli_credential_init() failed");
66                         talloc_free(ctx);
67                         return -1;
68                 }
69                 cli_credentials_set_conf(creds);
70                 cli_credentials_set_anonymous(creds);
71         } else if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) {
72                 /* get credential values from credentials object */
73                 creds = mprGetPtr(argv[0], "creds");
74                 if (creds == NULL) {
75                         ejsSetErrorMsg(eid, "userAuth requires a 'creds' first parameter");
76                         talloc_free(ctx);
77                         return -1;
78                 }
79         } else {
80                 ejsSetErrorMsg(eid, "NetContext invalid arguments, this function requires an object.");
81                 talloc_free(ctx);
82                 return -1;
83         }
84         ctx->cred = creds;
85
86         obj = mprObject("NetCtx");
87         mprSetPtrChild(&obj, "ctx", ctx);
88         
89         mprSetCFunction(&obj, "UserMgr", ejs_net_userman);
90         mprSetCFunction(&obj, "JoinDomain", ejs_net_join_domain);
91         mprSetCFunction(&obj, "SamSyncLdb", ejs_net_samsync_ldb);
92         mpr_Return(eid, obj);
93
94         return 0;
95 }
96
97
98 static int ejs_net_join_domain(MprVarHandle eid, int argc, struct MprVar **argv)
99 {
100         TALLOC_CTX *mem_ctx;
101         struct libnet_context *ctx;
102         struct libnet_Join *join;
103         NTSTATUS status;
104         ctx = mprGetThisPtr(eid, "ctx");
105         mem_ctx = talloc_new(mprMemCtx());
106
107         join = talloc(mem_ctx, struct libnet_Join);
108         if (!join) {
109                 talloc_free(mem_ctx);
110                 return -1;
111         }
112
113         /* prepare parameters for the join */
114         join->in.netbios_name  = NULL;
115         join->in.join_type     = SEC_CHAN_WKSTA;
116         join->in.domain_name   = cli_credentials_get_domain(ctx->cred);
117         join->in.level         = LIBNET_JOIN_AUTOMATIC;
118         join->out.error_string = NULL;
119
120         if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) {
121                 MprVar *netbios_name = mprGetProperty(argv[0], "netbios_name", NULL);
122                 MprVar *domain_name = mprGetProperty(argv[0], "domain_name", NULL);
123                 MprVar *join_type = mprGetProperty(argv[0], "join_type", NULL);
124                 if (netbios_name) {
125                         join->in.netbios_name = mprToString(netbios_name);
126                 }
127                 if (domain_name) {
128                         join->in.domain_name = mprToString(domain_name);
129                 }
130                 if (join_type) {
131                         join->in.join_type = mprToInt(join_type);
132                 }
133         }
134
135         if (!join->in.domain_name) {
136                 ejsSetErrorMsg(eid, "a domain must be specified for to join");
137                 talloc_free(mem_ctx);
138                 return -1;
139         }
140
141         /* do the domain join */
142         status = libnet_Join(ctx, join, join);
143         
144         if (!NT_STATUS_IS_OK(status)) {
145                 MprVar error_string = mprString(join->out.error_string);
146                 
147                 mprSetPropertyValue(argv[0], "error_string", error_string);
148                 mpr_Return(eid, mprCreateBoolVar(False));
149         } else {
150                 mpr_Return(eid, mprCreateBoolVar(True));
151         }
152         talloc_free(mem_ctx);
153         return 0;
154 }
155
156
157 static int ejs_net_samsync_ldb(MprVarHandle eid, int argc, struct MprVar **argv)
158 {
159         TALLOC_CTX *mem_ctx;
160         struct libnet_context *ctx;
161         struct libnet_samsync_ldb *samsync;
162         NTSTATUS status;
163         ctx = mprGetThisPtr(eid, "ctx");
164         mem_ctx = talloc_new(mprMemCtx());
165
166         samsync = talloc(mem_ctx, struct libnet_samsync_ldb);
167         if (!samsync) {
168                 talloc_free(mem_ctx);
169                 return -1;
170         }
171
172         /* prepare parameters for the samsync */
173         samsync->in.machine_account = NULL;
174         samsync->in.session_info = NULL;
175         samsync->in.binding_string = NULL;
176         samsync->out.error_string = NULL;
177
178         if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) {
179                 MprVar *credentials = mprGetProperty(argv[0], "machine_account", NULL);
180                 MprVar *session_info = mprGetProperty(argv[0], "session_info", NULL);
181                 if (credentials) {
182                         samsync->in.machine_account = talloc_get_type(mprGetPtr(credentials, "creds"), struct cli_credentials);
183                 }
184                 if (session_info) {
185                         samsync->in.session_info = talloc_get_type(mprGetPtr(session_info, "session_info"), struct auth_session_info);
186                 }
187         }
188
189         /* do the domain samsync */
190         status = libnet_samsync_ldb(ctx, samsync, samsync);
191         
192         if (!NT_STATUS_IS_OK(status)) {
193                 MprVar error_string = mprString(samsync->out.error_string);
194                 
195                 mprSetPropertyValue(argv[0], "error_string", error_string);
196                 mpr_Return(eid, mprCreateBoolVar(False));
197         } else {
198                 mpr_Return(eid, mprCreateBoolVar(True));
199         }
200         talloc_free(mem_ctx);
201         return 0;
202 }
203
204
205 /*
206   Usage:
207   usrCtx = net.UserMgr(domain);
208 */
209 static int ejs_net_userman(MprVarHandle eid, int argc, struct MprVar **argv)
210 {
211         TALLOC_CTX *mem_ctx;
212         struct libnet_context *ctx;
213         const char *userman_domain = NULL;
214         struct MprVar *obj = NULL;
215
216         ctx = mprGetThisPtr(eid, "ctx");
217         mem_ctx = talloc_new(mprMemCtx());
218
219         if (argc == 0) {
220                 userman_domain = cli_credentials_get_domain(ctx->cred);
221
222         } else if (argc == 1 && mprVarIsString(argv[0]->type)) {
223                 userman_domain = talloc_strdup(ctx, mprToString(argv[0]));
224
225         } else {
226                 ejsSetErrorMsg(eid, "too many arguments");
227                 goto done;
228         }
229         
230         if (!userman_domain) {
231                 ejsSetErrorMsg(eid, "a domain must be specified for user management");
232                 goto done;
233         }
234
235         obj = mprInitObject(eid, "NetUsrCtx", argc, argv);
236         mprSetPtrChild(obj, "ctx", ctx);
237         mprSetPtrChild(obj, "domain", userman_domain);
238
239         mprSetStringCFunction(obj, "Create", ejs_net_createuser);
240         mprSetStringCFunction(obj, "Delete", ejs_net_deleteuser);
241         mprSetStringCFunction(obj, "Info", ejs_net_userinfo);
242
243         return 0;
244 done:
245         talloc_free(mem_ctx);
246         return -1;
247 }
248
249
250 static int ejs_net_createuser(MprVarHandle eid, int argc, char **argv)
251 {
252         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
253         TALLOC_CTX *mem_ctx;
254         struct libnet_context *ctx;
255         const char *userman_domain = NULL;
256         struct libnet_CreateUser req;
257
258         if (argc != 1) {
259                 ejsSetErrorMsg(eid, "argument 1 must be a string");
260                 return -1;
261         }
262
263         ctx = mprGetThisPtr(eid, "ctx");
264         if (!ctx) {
265                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
266                 return -1;
267         }
268
269         userman_domain = mprGetThisPtr(eid, "domain");
270         if (!userman_domain) {
271                 ejsSetErrorMsg(eid, "domain property returns null pointer");
272                 return -1;
273         }
274         
275         mem_ctx = talloc_new(mprMemCtx());
276
277         req.in.domain_name = userman_domain;
278         req.in.user_name   = argv[0];
279
280         status = libnet_CreateUser(ctx, mem_ctx, &req);
281         if (!NT_STATUS_IS_OK(status)) {
282                 ejsSetErrorMsg(eid, "%s", req.out.error_string);
283         }
284
285         talloc_free(mem_ctx);
286         mpr_Return(eid, mprNTSTATUS(status));
287         return 0;
288 }
289
290
291 static int ejs_net_deleteuser(MprVarHandle eid, int argc, char **argv)
292 {
293         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
294         TALLOC_CTX *mem_ctx;
295         struct libnet_context *ctx;
296         const char *userman_domain = NULL;
297         struct libnet_DeleteUser req;
298
299         if (argc != 1) {
300                 ejsSetErrorMsg(eid, "argument 1 must be a string");
301                 return -1;
302         }
303
304         ctx = mprGetThisPtr(eid, "ctx");
305         if (!ctx) {
306                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
307                 return -1;
308         }
309
310         userman_domain = mprGetThisPtr(eid, "domain");
311         if (!userman_domain) {
312                 ejsSetErrorMsg(eid, "domain property returns null pointer");
313                 return -1;
314         }
315         
316         mem_ctx = talloc_new(mprMemCtx());
317
318         req.in.domain_name = userman_domain;
319         req.in.user_name   = argv[0];
320
321         status = libnet_DeleteUser(ctx, mem_ctx, &req);
322         if (!NT_STATUS_IS_OK(status)) {
323                 ejsSetErrorMsg(eid, "%s", req.out.error_string);
324         }
325
326         talloc_free(mem_ctx);
327         mpr_Return(eid, mprNTSTATUS(status));
328         return 0;
329 }
330
331
332 static int ejs_net_userinfo(MprVarHandle eid, int argc, char **argv)
333 {
334         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
335         TALLOC_CTX *mem_ctx;
336         struct libnet_context *ctx;
337         const char *userman_domain = NULL;
338         struct libnet_UserInfo req;
339         struct MprVar mprUserInfo;
340         struct MprVar mprAccountName, mprFullName, mprDescription;
341         struct MprVar mprHomeDir, mprHomeDrive, mprComment;
342         struct MprVar mprLogonScript;
343         struct MprVar mprAcctExpiry, mprAllowPassChange, mprForcePassChange;
344
345         if (argc != 1) {
346                 ejsSetErrorMsg(eid, "argument 1 must be a string");
347                 return -1;
348         }
349
350         ctx = mprGetThisPtr(eid, "ctx");
351         if (!ctx) {
352                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
353                 return -1;
354         }
355
356         userman_domain = mprGetThisPtr(eid, "domain");
357         if (!userman_domain) {
358                 ejsSetErrorMsg(eid, "domain property returns null pointer");
359                 return -1;
360         }
361
362         mem_ctx = talloc_new(mprMemCtx());
363         
364         req.in.domain_name = userman_domain;
365         req.in.user_name   = argv[0];
366         
367         status = libnet_UserInfo(ctx, mem_ctx, &req);
368         if (!NT_STATUS_IS_OK(status)) {
369                 ejsSetErrorMsg(eid, "%s", req.out.error_string);
370         }
371
372         /* create UserInfo object */
373         mprUserInfo = mprObject("UserInfo");
374
375         mprAccountName = mprString(req.out.account_name);
376         mprFullName = mprString(req.out.full_name);
377         mprDescription = mprString(req.out.description);
378         mprHomeDir = mprString(req.out.home_directory);
379         mprHomeDrive = mprString(req.out.home_drive);
380         mprComment = mprString(req.out.comment);
381         mprLogonScript = mprString(req.out.logon_script);
382         mprAcctExpiry = mprString(timestring(mem_ctx, req.out.acct_expiry->tv_sec));
383         mprAllowPassChange = mprString(timestring(mem_ctx, req.out.allow_password_change->tv_sec));
384         mprForcePassChange = mprString(timestring(mem_ctx, req.out.force_password_change->tv_sec));
385
386         status = mprSetVar(&mprUserInfo, "AccountName", mprAccountName);
387         if (!NT_STATUS_IS_OK(status)) goto done;
388         status = mprSetVar(&mprUserInfo, "FullName", mprFullName);
389         if (!NT_STATUS_IS_OK(status)) goto done;
390         status = mprSetVar(&mprUserInfo, "Description", mprDescription);
391         if (!NT_STATUS_IS_OK(status)) goto done;
392         status = mprSetVar(&mprUserInfo, "HomeDirectory", mprHomeDir);
393         if (!NT_STATUS_IS_OK(status)) goto done;
394         status = mprSetVar(&mprUserInfo, "HomeDrive", mprHomeDrive);
395         if (!NT_STATUS_IS_OK(status)) goto done;
396         status = mprSetVar(&mprUserInfo, "Comment", mprComment);
397         if (!NT_STATUS_IS_OK(status)) goto done;
398         status = mprSetVar(&mprUserInfo, "LogonScript", mprLogonScript);
399         if (!NT_STATUS_IS_OK(status)) goto done;
400         status = mprSetVar(&mprUserInfo, "AcctExpiry", mprAcctExpiry);
401         if (!NT_STATUS_IS_OK(status)) goto done;
402         status = mprSetVar(&mprUserInfo, "AllowPasswordChange", mprAllowPassChange);
403         if (!NT_STATUS_IS_OK(status)) goto done;
404         status = mprSetVar(&mprUserInfo, "ForcePasswordChange", mprForcePassChange);
405         if (!NT_STATUS_IS_OK(status)) goto done;
406
407 done:
408         talloc_free(mem_ctx);
409         mpr_Return(eid, mprUserInfo);
410         return 0;
411 }
412
413
414 void ejsnet_setup(void)
415 {
416         ejsDefineCFunction(-1, "NetContext", ejs_net_context, NULL, MPR_VAR_SCRIPT_HANDLE);
417 }