libnet: Make UserInfo accept a SID as input as well, fix wb_cmd_getpwuid
[kai/samba-autobuild/.git] / source4 / scripting / ejs / ejsnet / net_user.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    provides interfaces to libnet calls from ejs scripts
5
6    Copyright (C) Rafal Szczesniak  2005-2007
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 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "lib/appweb/ejs/ejs.h"
24 #include "libnet/libnet.h"
25 #include "scripting/ejs/ejsnet/proto.h"
26 #include "scripting/ejs/smbcalls.h"
27 #include "events/events.h"
28 #include "auth/credentials/credentials.h"
29
30
31 static int ejs_net_createuser(MprVarHandle eid, int argc, char **argv);
32 static int ejs_net_deleteuser(MprVarHandle eid, int argc, char **argv);
33 static int ejs_net_userinfo(MprVarHandle eid, int argc, char **argv);
34 static int ejs_net_userlist(MprVarHandle eid, int argc, struct MprVar **argv);
35
36
37 /*
38   Usage:
39   usrCtx = net.UserMgr(domain = <default from credentials>);
40 */
41 int ejs_net_userman(MprVarHandle eid, int argc, struct MprVar **argv)
42 {
43         struct libnet_context *ctx;
44         const char *userman_domain = NULL;
45         struct MprVar obj;
46
47         /* libnet context */
48         ctx = (struct libnet_context *)mprGetThisPtr(eid, "ctx");
49         if (ctx == NULL) {
50                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
51                 return 0;
52         }
53
54         /* fetch the arguments: domain name */
55         if (argc == 0) {
56                 /* default domain name is supplied in credentials */
57                 userman_domain = cli_credentials_get_domain(ctx->cred);
58
59         } else if (argc == 1 && mprVarIsString(argv[0]->type)) {
60                 /* domain name can also be specified explicitly 
61                    (e.g. to connect BUILTIN domain) */
62                 userman_domain = mprToString(argv[0]);
63
64         } else {
65                 ejsSetErrorMsg(eid, "too many arguments");
66                 return 0;
67         }
68
69         /* any domain name must be specified anyway */
70         if (userman_domain == NULL) {
71                 ejsSetErrorMsg(eid, "a domain must be specified for user management");
72                 return 0;
73         }
74
75         /* create 'net user' subcontext */
76         obj = mprObject("NetUsrCtx");
77
78         /* we need to make a copy of the string for this object */
79         userman_domain = talloc_strdup(ctx, userman_domain);
80
81         /* add properties */
82         mprSetPtrChild(&obj, "ctx", ctx);
83         mprSetPtrChild(&obj, "domain", userman_domain);
84
85         /* add methods */
86         mprSetStringCFunction(&obj, "Create", ejs_net_createuser);
87         mprSetStringCFunction(&obj, "Delete", ejs_net_deleteuser);
88         mprSetStringCFunction(&obj, "Info", ejs_net_userinfo);
89         mprSetCFunction(&obj, "List", ejs_net_userlist);
90
91         /* set the object returned by this function */
92         mpr_Return(eid, obj);
93
94         return 0;
95 }
96
97
98 /*
99   Usage:
100   NTSTATUS = NetUsrCtx.Create(Username)
101 */
102 static int ejs_net_createuser(MprVarHandle eid, int argc, char **argv)
103 {
104         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
105         TALLOC_CTX *mem_ctx;
106         struct libnet_context *ctx;
107         const char *userman_domain = NULL;
108         const char *username = NULL;
109         struct libnet_CreateUser req;
110
111         mem_ctx = talloc_new(mprMemCtx());
112         if (mem_ctx == NULL) {
113                 ejsSetErrorMsg(eid, "could not create memory context - out of memory");
114                 goto done;
115         }
116
117         /* fetch the arguments: username */
118         if (argc == 0) {
119                 ejsSetErrorMsg(eid, "too little arguments");
120                 goto done;
121
122         } else if (argc == 1) {
123                 username = argv[0];
124
125         } else {
126                 ejsSetErrorMsg(eid, "too many arguments");
127                 goto done;
128         }
129         
130         /* libnet context */
131         ctx = (struct libnet_context *)mprGetThisPtr(eid, "ctx");
132         if (ctx == NULL) {
133                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
134                 goto done;
135         }
136
137         /* domain where the account is to be created */
138         userman_domain = (const char *)mprGetThisPtr(eid, "domain");
139         if (userman_domain == NULL) {
140                 ejsSetErrorMsg(eid, "domain property returns null pointer");
141                 goto done;
142         }
143         
144         /* call the libnet function */
145         req.in.domain_name = userman_domain;
146         req.in.user_name   = argv[0];
147
148         status = libnet_CreateUser(ctx, mem_ctx, &req);
149         if (!NT_STATUS_IS_OK(status)) {
150                 ejsSetErrorMsg(eid, "%s", req.out.error_string);
151         }
152
153 done:
154         talloc_free(mem_ctx);
155         mpr_Return(eid, mprNTSTATUS(status));
156         return 0;
157 }
158
159
160 /*
161   Usage:
162   NTSTATUS = NetUsrCtx.Delete(Username)
163 */
164 static int ejs_net_deleteuser(MprVarHandle eid, int argc, char **argv)
165 {
166         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
167         TALLOC_CTX *mem_ctx;
168         struct libnet_context *ctx;
169         const char *userman_domain = NULL;
170         const char *username = NULL;
171         struct libnet_DeleteUser req;
172
173         mem_ctx = talloc_new(mprMemCtx());
174         if (mem_ctx == NULL) {
175                 ejsSetErrorMsg(eid, "could not create memory context - out of memory");
176                 goto done;
177         }
178
179         /* fetch the arguments: username */
180         if (argc == 0) {
181                 ejsSetErrorMsg(eid, "too little arguments");
182                 goto done;
183
184         } else if (argc == 1) {
185                 username = argv[0];
186
187         } else {
188                 ejsSetErrorMsg(eid, "too many arguments");
189                 goto done;
190         }
191
192         /* libnet context */
193         ctx = mprGetThisPtr(eid, "ctx");
194         if (ctx == NULL) {
195                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
196                 goto done;
197         }
198
199         /* domain where the account is to be deleted */
200         userman_domain = mprGetThisPtr(eid, "domain");
201         if (!userman_domain) {
202                 ejsSetErrorMsg(eid, "domain property returns null pointer");
203                 goto done;
204         }
205         
206         /* call the libnet function */
207         req.in.domain_name = userman_domain;
208         req.in.user_name   = username;
209
210         status = libnet_DeleteUser(ctx, mem_ctx, &req);
211         if (!NT_STATUS_IS_OK(status)) {
212                 ejsSetErrorMsg(eid, "%s", req.out.error_string);
213         }
214
215 done:
216         talloc_free(mem_ctx);
217         mpr_Return(eid, mprNTSTATUS(status));
218         return 0;
219 }
220
221
222 /*
223   Usage:
224   UserInfo = NetUsrCtx.Info(Username)
225 */
226 static int ejs_net_userinfo(MprVarHandle eid, int argc, char **argv)
227 {
228         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
229         TALLOC_CTX *mem_ctx;
230         struct libnet_context *ctx;
231         const char *userman_domain = NULL;
232         const char *username = NULL;
233         struct libnet_UserInfo req;
234         struct MprVar mprUserInfo;
235
236         mem_ctx = talloc_new(mprMemCtx());
237         if (mem_ctx == NULL) {
238                 ejsSetErrorMsg(eid, "could not create memory context - out of memory");
239                 goto done;
240         }
241         
242         /* fetch the arguments: username */
243         if (argc == 0) {
244                 ejsSetErrorMsg(eid, "too little arguments");
245                 goto done;
246
247         } else if (argc == 1) {
248                 username = argv[0];
249
250         } else {
251                 ejsSetErrorMsg(eid, "too many arguments");
252                 goto done;
253         }
254
255         /* libnet context */
256         ctx = (struct libnet_context *)mprGetThisPtr(eid, "ctx");
257         if (ctx == NULL) {
258                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
259                 goto done;
260         }
261
262         /* domain where the user account is to be queried */
263         userman_domain = mprGetThisPtr(eid, "domain");
264         if (userman_domain == NULL) {
265                 ejsSetErrorMsg(eid, "domain property returns null pointer");
266                 return -1;
267         }
268
269         /* call the libnet function */
270         req.in.domain_name = userman_domain;
271         req.in.data.user_name   = username;
272         req.in.level = USER_INFO_BY_NAME;
273
274         status = libnet_UserInfo(ctx, mem_ctx, &req);
275         if (!NT_STATUS_IS_OK(status)) {
276                 ejsSetErrorMsg(eid, "%s", req.out.error_string);
277                 
278                 /* create null object to return */
279                 mprUserInfo = mprCreateNullVar();
280                 goto done;
281         }
282
283         /* create UserInfo object */
284         mprUserInfo = mprCreateUserInfo(ctx, &req);
285
286 done:
287         talloc_free(mem_ctx);
288         mpr_Return(eid, mprUserInfo);
289         return 0;
290 }
291
292
293 /*
294   Usage:
295   UserListCtx = NetUsrCtx.List(UserListCtx)
296 */
297 static int ejs_net_userlist(MprVarHandle eid, int argc, struct MprVar **argv)
298 {
299         TALLOC_CTX *mem_ctx;
300         NTSTATUS status;
301         struct libnet_context *ctx;
302         const char *userlist_domain;
303         int page_size = 512;         /* TODO: this should be specified in a nicer way */
304         struct libnet_UserList req;
305         struct MprVar mprListCtx, *mprInListCtx;
306         
307         mem_ctx = talloc_new(mprMemCtx());
308         if (mem_ctx == NULL) {
309                 ejsSetErrorMsg(eid, "could not create memory context - out of memory");
310                 goto done;
311         }
312         
313         /* fetch the arguments */
314         if (argc == 0) {
315                 ejsSetErrorMsg(eid, "too little arguments");
316                 goto done;
317
318         } else if (argc == 1) {
319                 if (mprVarIsObject(argv[0]->type)) {
320                         /* this is a continuation call */
321                         mprInListCtx = argv[0];
322                         req.in.resume_index = mprListGetResumeIndex(mprInListCtx);
323
324                 } else {
325                         /* this is a first call */
326                         req.in.resume_index = 0;
327                 }
328
329         } else {
330                 ejsSetErrorMsg(eid, "too many arguments");
331                 goto done;
332         }
333
334         /* libnet context */
335         ctx = (struct libnet_context *)mprGetThisPtr(eid, "ctx");
336         if (ctx == NULL) {
337                 ejsSetErrorMsg(eid, "ctx property returns null pointer");
338                 goto done;
339         }
340         
341         /* domain where user accounts are to be enumerated */
342         userlist_domain = mprGetThisPtr(eid, "domain");
343         if (userlist_domain == NULL) {
344                 ejsSetErrorMsg(eid, "domain property returns null pointer");
345                 goto done;
346         }
347
348         /* call the libnet function */
349         req.in.domain_name   = userlist_domain;
350         req.in.page_size     = page_size;
351         
352         status = libnet_UserList(ctx, mem_ctx, &req);
353         mprListCtx = mprUserListCtx(mem_ctx, &req, status);
354
355 done:
356         talloc_free(mem_ctx);
357         mpr_Return(eid, mprListCtx);
358         return 0;
359 }