Release alpha15.
[nivanova/samba-autobuild/.git] / source3 / utils / net_rap.c
1 /*
2    Samba Unix/Linux SMB client library
3    Distributed SMB/CIFS Server Management Utility
4    Copyright (C) 2001 Steve French  (sfrench@us.ibm.com)
5    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
6    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
7    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
8
9    Originally written by Steve and Jim. Largely rewritten by tridge in
10    November 2001.
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
24
25 #include "includes.h"
26 #include "../librpc/gen_ndr/rap.h"
27 #include "../librpc/gen_ndr/svcctl.h"
28 #include "utils/net.h"
29 #include "libsmb/clirap.h"
30
31 /* The following messages were for error checking that is not properly
32    reported at the moment.  Which should be reinstated? */
33 #define ERRMSG_TARGET_WG_NOT_VALID      "\nTarget workgroup option not valid "\
34                                         "except on net rap server command, ignored"
35 #define ERRMSG_INVALID_HELP_OPTION      "\nInvalid help option\n"
36
37 #define ERRMSG_BOTH_SERVER_IPADDRESS    "\nTarget server and IP address both "\
38   "specified. Do not set both at the same time.  The target IP address was used\n"
39
40 static int errmsg_not_implemented(void)
41 {
42         d_printf(_("\nNot implemented\n"));
43         return 0;
44 }
45
46 int net_rap_file_usage(struct net_context *c, int argc, const char **argv)
47 {
48         return net_file_usage(c, argc, argv);
49 }
50
51 /***************************************************************************
52   list info on an open file
53 ***************************************************************************/
54 static void file_fn(const char * pPath, const char * pUser, uint16 perms,
55                     uint16 locks, uint32 id)
56 {
57         d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
58                  id, pUser, perms, locks, pPath);
59 }
60
61 static void one_file_fn(const char *pPath, const char *pUser, uint16 perms,
62                         uint16 locks, uint32 id)
63 {
64         d_printf(_("File ID          %d\n"
65                    "User name        %s\n"
66                    "Locks            0x%-4.2x\n"
67                    "Path             %s\n"
68                    "Permissions      0x%x\n"),
69                  id, pUser, locks, pPath, perms);
70 }
71
72
73 static int rap_file_close(struct net_context *c, int argc, const char **argv)
74 {
75         struct cli_state *cli;
76         int ret;
77         if (argc == 0 || c->display_usage) {
78                 return net_rap_file_usage(c, argc, argv);
79         }
80
81         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
82                 return -1;
83
84         ret = cli_NetFileClose(cli, atoi(argv[0]));
85         cli_shutdown(cli);
86         return ret;
87 }
88
89 static int rap_file_info(struct net_context *c, int argc, const char **argv)
90 {
91         struct cli_state *cli;
92         int ret;
93         if (argc == 0 || c->display_usage)
94                 return net_rap_file_usage(c, argc, argv);
95
96         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
97                 return -1;
98
99         ret = cli_NetFileGetInfo(cli, atoi(argv[0]), one_file_fn);
100         cli_shutdown(cli);
101         return ret;
102 }
103
104 static int rap_file_user(struct net_context *c, int argc, const char **argv)
105 {
106         struct cli_state *cli;
107         int ret;
108
109         if (argc == 0 || c->display_usage)
110                 return net_rap_file_usage(c, argc, argv);
111
112         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
113                 return -1;
114
115         /* list open files */
116
117         d_printf(_("\nEnumerating open files on remote server:\n\n"
118                    "\nFileId  Opened by            Perms  Locks  Path \n"
119                    "------  ---------            -----  -----  ---- \n"));
120         ret = cli_NetFileEnum(cli, argv[0], NULL, file_fn);
121
122         if (ret == -1)
123                 d_printf(_("\nOperation not supported by server!\n\n"));
124
125         cli_shutdown(cli);
126         return ret;
127 }
128
129 int net_rap_file(struct net_context *c, int argc, const char **argv)
130 {
131         struct functable func[] = {
132                 {
133                         "close",
134                         rap_file_close,
135                         NET_TRANSPORT_RAP,
136                         N_("Close specified file on server"),
137                         N_("net rap file close\n"
138                            "    Close specified file on server")
139                 },
140                 {
141                         "user",
142                         rap_file_user,
143                         NET_TRANSPORT_RAP,
144                         N_("List all files opened by username"),
145                         N_("net rap file user\n"
146                            "    List all files opened by username")
147                 },
148                 {
149                         "info",
150                         rap_file_info,
151                         NET_TRANSPORT_RAP,
152                         N_("Display info about an opened file"),
153                         N_("net rap file info\n"
154                            "    Display info about an opened file")
155                 },
156                 {NULL, NULL, 0, NULL, NULL}
157         };
158
159         if (argc == 0) {
160                 struct cli_state *cli;
161                 int ret;
162
163                 if (c->display_usage) {
164                         d_printf(_("Usage:\n"));
165                         d_printf(_("net rap file\n"
166                                    "    List all open files on rempte "
167                                    "server\n"));
168                         net_display_usage_from_functable(func);
169                         return 0;
170                 }
171
172                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
173                         return -1;
174
175                 /* list open files */
176
177                 d_printf(_("\nEnumerating open files on remote server:\n\n"
178                            "\nFileId  Opened by            Perms  Locks  Path\n"
179                            "------  ---------            -----  -----  ----\n"));
180                 ret = cli_NetFileEnum(cli, NULL, NULL, file_fn);
181
182                 if (ret == -1)
183                         d_printf(_("\nOperation not supported by server!\n\n"));
184
185                 cli_shutdown(cli);
186                 return ret;
187         }
188
189         return net_run_function(c, argc, argv, "net rap file", func);
190 }
191
192 int net_rap_share_usage(struct net_context *c, int argc, const char **argv)
193 {
194         return net_share_usage(c, argc, argv);
195 }
196
197 static void long_share_fn(const char *share_name, uint32 type,
198                           const char *comment, void *state)
199 {
200         d_printf("%-12s %-8.8s %-50s\n",
201                  share_name, net_share_type_str(type), comment);
202 }
203
204 static void share_fn(const char *share_name, uint32 type,
205                      const char *comment, void *state)
206 {
207         d_printf("%s\n", share_name);
208 }
209
210 static int rap_share_delete(struct net_context *c, int argc, const char **argv)
211 {
212         struct cli_state *cli;
213         int ret;
214
215         if (argc == 0 || c->display_usage) {
216                 return net_rap_share_usage(c, argc, argv);
217         }
218
219         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
220                 return -1;
221
222         ret = cli_NetShareDelete(cli, argv[0]);
223         cli_shutdown(cli);
224         return ret;
225 }
226
227 static int rap_share_add(struct net_context *c, int argc, const char **argv)
228 {
229         struct cli_state *cli;
230         int ret;
231
232         struct rap_share_info_2 sinfo;
233         char *p;
234         char *sharename;
235
236         if (argc == 0 || c->display_usage) {
237                 return net_rap_share_usage(c, argc, argv);
238         }
239
240         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
241                 return -1;
242
243         sharename = SMB_STRDUP(argv[0]);
244         p = strchr(sharename, '=');
245         if (p == NULL) {
246                 d_printf(_("Server path not specified\n"));
247                 SAFE_FREE(sharename);
248                 return net_rap_share_usage(c, argc, argv);
249         }
250         *p = 0;
251         strlcpy((char *)sinfo.share_name, sharename, sizeof(sinfo.share_name));
252         sinfo.reserved1 = '\0';
253         sinfo.share_type = 0;
254         sinfo.comment = c->opt_comment ? smb_xstrdup(c->opt_comment) : "";
255         sinfo.perms = 0;
256         sinfo.maximum_users = c->opt_maxusers;
257         sinfo.active_users = 0;
258         sinfo.path = p+1;
259         memset(sinfo.password, '\0', sizeof(sinfo.password));
260         sinfo.reserved2 = '\0';
261
262         ret = cli_NetShareAdd(cli, &sinfo);
263         cli_shutdown(cli);
264         SAFE_FREE(sharename);
265         return ret;
266 }
267
268
269 int net_rap_share(struct net_context *c, int argc, const char **argv)
270 {
271         struct functable func[] = {
272                 {
273                         "delete",
274                         rap_share_delete,
275                         NET_TRANSPORT_RAP,
276                         N_("Delete a share from server"),
277                         N_("net rap share delete\n"
278                            "    Delete a share from server")
279                 },
280                 {
281                         "close",
282                         rap_share_delete,
283                         NET_TRANSPORT_RAP,
284                         N_("Delete a share from server"),
285                         N_("net rap share close\n"
286                            "    Delete a share from server\n"
287                            "    Alias for net rap share delete")
288                 },
289                 {
290                         "add",
291                         rap_share_add,
292                         NET_TRANSPORT_RAP,
293                         N_("Add a share to server"),
294                         N_("net rap share add\n"
295                            "    Add a share to server")
296                 },
297                 {NULL, NULL, 0, NULL, NULL}
298         };
299
300         if (argc == 0) {
301                 struct cli_state *cli;
302                 int ret;
303
304                 if (c->display_usage) {
305                         d_printf(_("Usage:\n"));
306                         d_printf(_("net rap share\n"
307                                    "    List all shares on remote server\n"));
308                         net_display_usage_from_functable(func);
309                         return 0;
310                 }
311
312                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
313                         return -1;
314
315                 if (c->opt_long_list_entries) {
316                         d_printf(_(
317         "\nEnumerating shared resources (exports) on remote server:\n\n"
318         "\nShare name   Type     Description\n"
319         "----------   ----     -----------\n"));
320                         ret = cli_RNetShareEnum(cli, long_share_fn, NULL);
321                 } else {
322                         ret = cli_RNetShareEnum(cli, share_fn, NULL);
323                 }
324                 cli_shutdown(cli);
325                 return ret;
326         }
327
328         return net_run_function(c, argc, argv, "net rap share", func);
329 }
330
331 int net_rap_session_usage(struct net_context *c, int argc, const char **argv)
332 {
333         d_printf(_(
334          "\nnet rap session [misc. options] [targets]"
335          "\n\tenumerates all active SMB/CIFS sessions on target server\n"));
336         d_printf(_(
337          "\nnet rap session DELETE <client_name> [misc. options] [targets] \n"
338          "\tor"
339          "\nnet rap session CLOSE <client_name> [misc. options] [targets]"
340          "\n\tDeletes (closes) a session from specified client to server\n"));
341         d_printf(_(
342         "\nnet rap session INFO <client_name>"
343         "\n\tEnumerates all open files in specified session\n"));
344
345         net_common_flags_usage(c, argc, argv);
346         return -1;
347 }
348
349 static void list_sessions_func(char *wsname, char *username, uint16 conns,
350                         uint16 opens, uint16 users, uint32 sess_time,
351                         uint32 idle_time, uint32 user_flags, char *clitype)
352 {
353         int hrs = idle_time / 3600;
354         int min = (idle_time / 60) % 60;
355         int sec = idle_time % 60;
356
357         d_printf("\\\\%-18.18s %-20.20s %-18.18s %5d %2.2d:%2.2d:%2.2d\n",
358                  wsname, username, clitype, opens, hrs, min, sec);
359 }
360
361 static void display_session_func(const char *wsname, const char *username,
362                                  uint16 conns, uint16 opens, uint16 users,
363                                  uint32 sess_time, uint32 idle_time,
364                                  uint32 user_flags, const char *clitype)
365 {
366         int ihrs = idle_time / 3600;
367         int imin = (idle_time / 60) % 60;
368         int isec = idle_time % 60;
369         int shrs = sess_time / 3600;
370         int smin = (sess_time / 60) % 60;
371         int ssec = sess_time % 60;
372         d_printf(_("User name       %-20.20s\n"
373                    "Computer        %-20.20s\n"
374                    "Guest logon     %-20.20s\n"
375                    "Client Type     %-40.40s\n"
376                    "Sess time       %2.2d:%2.2d:%2.2d\n"
377                    "Idle time       %2.2d:%2.2d:%2.2d\n"),
378                  username, wsname,
379                  (user_flags&0x0)?_("yes"):_("no"), clitype,
380                  shrs, smin, ssec, ihrs, imin, isec);
381 }
382
383 static void display_conns_func(uint16 conn_id, uint16 conn_type, uint16 opens,
384                                uint16 users, uint32 conn_time,
385                                const char *username, const char *netname)
386 {
387         d_printf("%-14.14s %-8.8s %5d\n",
388                  netname, net_share_type_str(conn_type), opens);
389 }
390
391 static int rap_session_info(struct net_context *c, int argc, const char **argv)
392 {
393         const char *sessname;
394         struct cli_state *cli;
395         int ret;
396
397         if (argc == 0 || c->display_usage)
398                 return net_rap_session_usage(c, argc, argv);
399
400         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
401                 return -1;
402
403         sessname = argv[0];
404
405         ret = cli_NetSessionGetInfo(cli, sessname, display_session_func);
406         if (ret < 0) {
407                 cli_shutdown(cli);
408                 return ret;
409         }
410
411         d_printf(_("Share name     Type     # Opens\n-------------------------"
412                    "-----------------------------------------------------\n"));
413         ret = cli_NetConnectionEnum(cli, sessname, display_conns_func);
414         cli_shutdown(cli);
415         return ret;
416 }
417
418 static int rap_session_delete(struct net_context *c, int argc, const char **argv)
419 {
420         struct cli_state *cli;
421         int ret;
422
423         if (argc == 0 || c->display_usage)
424                 return net_rap_session_usage(c, argc, argv);
425
426         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
427                 return -1;
428
429         ret = cli_NetSessionDel(cli, argv[0]);
430         cli_shutdown(cli);
431         return ret;
432 }
433
434 int net_rap_session(struct net_context *c, int argc, const char **argv)
435 {
436         struct functable func[] = {
437                 {
438                         "info",
439                         rap_session_info,
440                         NET_TRANSPORT_RAP,
441                         N_("Display information about session"),
442                         N_("net rap session info\n"
443                            "    Display information about session")
444                 },
445                 {
446                         "delete",
447                         rap_session_delete,
448                         NET_TRANSPORT_RAP,
449                         N_("Close specified session"),
450                         N_("net rap session delete\n"
451                            "    Close specified session\n"
452                            "    Alias for net rap session close")
453                 },
454                 {
455                         "close",
456                         rap_session_delete,
457                         NET_TRANSPORT_RAP,
458                         N_("Close specified session"),
459                         N_("net rap session close\n"
460                            "    Close specified session")
461                 },
462                 {NULL, NULL, 0, NULL, NULL}
463         };
464
465         if (argc == 0) {
466                 struct cli_state *cli;
467                 int ret;
468
469                 if (c->display_usage) {
470                         d_printf(_("Usage:\n"));
471                         d_printf(_("net rap session\n"
472                                    "    List all open sessions on remote "
473                                    "server\n"));
474                         net_display_usage_from_functable(func);
475                         return 0;
476                 }
477
478                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
479                         return -1;
480
481                 d_printf(_("Computer             User name            "
482                            "Client Type        Opens Idle time\n"
483                            "------------------------------------------"
484                            "------------------------------------\n"));
485                 ret = cli_NetSessionEnum(cli, list_sessions_func);
486
487                 cli_shutdown(cli);
488                 return ret;
489         }
490
491         return net_run_function(c, argc, argv, "net rap session", func);
492 }
493
494 /****************************************************************************
495 list a server name
496 ****************************************************************************/
497 static void display_server_func(const char *name, uint32 m,
498                                 const char *comment, void * reserved)
499 {
500         d_printf("\t%-16.16s     %s\n", name, comment);
501 }
502
503 static int net_rap_server_name(struct net_context *c, int argc, const char *argv[])
504 {
505         struct cli_state *cli;
506         char *name;
507
508         if (c->display_usage) {
509                 d_printf("%s\n%s",
510                          _("Usage:"),
511                          _("net rap server name\n"
512                            "    Get the name of the server\n"));
513                 return 0;
514         }
515
516         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
517                 return -1;
518
519         if (!cli_get_server_name(NULL, cli, &name)) {
520                 d_fprintf(stderr, _("cli_get_server_name failed\n"));
521                 cli_shutdown(cli);
522                 return -1;
523         }
524
525         d_printf(_("Server name = %s\n"), name);
526
527         TALLOC_FREE(name);
528         cli_shutdown(cli);
529         return 0;
530 }
531
532 static int net_rap_server_domain(struct net_context *c, int argc,
533                                  const char **argv)
534 {
535         struct cli_state *cli;
536         int ret;
537
538         if (c->display_usage) {
539                 d_printf("%s\n%s",
540                          _("Usage:"),
541                          _("net rap server domain\n"
542                            "    Enumerate servers in this domain/workgroup\n"));
543                 return 0;
544         }
545
546         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
547                 return -1;
548
549         d_printf(_("\nEnumerating servers in this domain or workgroup: \n\n"
550                    "\tServer name          Server description\n"
551                    "\t-------------        ----------------------------\n"));
552
553         ret = cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL,
554                                 display_server_func,NULL);
555         cli_shutdown(cli);
556         return ret;
557 }
558
559 int net_rap_server(struct net_context *c, int argc, const char **argv)
560 {
561         struct functable func[] = {
562                 {
563                         "name",
564                         net_rap_server_name,
565                         NET_TRANSPORT_RAP,
566                         N_("Get the name of the server"),
567                         N_("net rap server name\n"
568                            "    Get the name of the server")
569                 },
570                 {
571                         "domain",
572                         net_rap_server_domain,
573                         NET_TRANSPORT_RAP,
574                         N_("Get the servers in this domain/workgroup"),
575                         N_("net rap server domain\n"
576                            "    Get the servers in this domain/workgroup")
577                 },
578                 {NULL, NULL, 0, NULL, NULL}
579         };
580
581         /* smb4k uses 'net [rap|rpc] server domain' to query servers in a domain */
582         /* Fall through for 'domain', any other forms will cause to show usage message */
583         return net_run_function(c, argc, argv, "net rap server", func);
584
585 }
586
587 int net_rap_domain_usage(struct net_context *c, int argc, const char **argv)
588 {
589         d_printf(_("net rap domain [misc. options] [target]\n\tlists the"
590                    " domains or workgroups visible on the current network\n"));
591
592         net_common_flags_usage(c, argc, argv);
593         return -1;
594 }
595
596 int net_rap_domain(struct net_context *c, int argc, const char **argv)
597 {
598         struct cli_state *cli;
599         int ret;
600
601         if (c->display_usage)
602                 return net_rap_domain_usage(c, argc, argv);
603
604         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
605                 return -1;
606
607         d_printf(_("\nEnumerating domains:\n\n"
608                    "\tDomain name          Server name of Browse Master\n"
609                    "\t-------------        ----------------------------\n"));
610
611         ret = cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM,
612                                 display_server_func,NULL);
613         cli_shutdown(cli);
614         return ret;
615 }
616
617 int net_rap_printq_usage(struct net_context *c, int argc, const char **argv)
618 {
619         d_printf(_(
620          "net rap printq [misc. options] [targets]\n"
621          "\tor\n"
622          "net rap printq info [<queue_name>] [misc. options] [targets]\n"
623          "\tlists the specified queue and jobs on the target server.\n"
624          "\tIf the queue name is not specified, all queues are listed.\n\n"));
625         d_printf(_(
626          "net rap printq delete [<queue name>] [misc. options] [targets]\n"
627          "\tdeletes the specified job number on the target server, or the\n"
628          "\tprinter queue if no job number is specified\n"));
629
630         net_common_flags_usage(c, argc, argv);
631
632         return -1;
633 }
634
635 static void enum_queue(const char *queuename, uint16 pri, uint16 start,
636                        uint16 until, const char *sep, const char *pproc,
637                        const char *dest, const char *qparms,
638                        const char *qcomment, uint16 status, uint16 jobcount)
639 {
640         d_printf(_("%-17.17s Queue %5d jobs                      "),
641                  queuename, jobcount);
642
643         switch (status) {
644         case 0:
645                 d_printf(_("*Printer Active*\n"));
646                 break;
647         case 1:
648                 d_printf(_("*Printer Paused*\n"));
649                 break;
650         case 2:
651                 d_printf(_("*Printer error*\n"));
652                 break;
653         case 3:
654                 d_printf(_("*Delete Pending*\n"));
655                 break;
656         default:
657                 d_printf(_("**UNKNOWN STATUS**\n"));
658         }
659 }
660
661 static void enum_jobs(uint16 jobid, const char *ownername,
662                       const char *notifyname, const char *datatype,
663                       const char *jparms, uint16 pos, uint16 status,
664                       const char *jstatus, unsigned int submitted, unsigned int jobsize,
665                       const char *comment)
666 {
667         d_printf("     %-23.23s %5d %9d            ",
668                  ownername, jobid, jobsize);
669         switch (status) {
670         case 0:
671                 d_printf(_("Waiting\n"));
672                 break;
673         case 1:
674                 d_printf(_("Held in queue\n"));
675                 break;
676         case 2:
677                 d_printf(_("Spooling\n"));
678                 break;
679         case 3:
680                 d_printf(_("Printing\n"));
681                 break;
682         default:
683                 d_printf(_("**UNKNOWN STATUS**\n"));
684         }
685 }
686
687 #define PRINTQ_ENUM_DISPLAY \
688     _("Print queues at \\\\%s\n\n"\
689       "Name                         Job #      Size            Status\n\n"\
690       "------------------------------------------------------------------"\
691       "-------------\n")
692
693 static int rap_printq_info(struct net_context *c, int argc, const char **argv)
694 {
695         struct cli_state *cli;
696         int ret;
697
698         if (argc == 0 || c->display_usage)
699                 return net_rap_printq_usage(c, argc, argv);
700
701         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
702                 return -1;
703
704         d_printf(PRINTQ_ENUM_DISPLAY, cli->desthost); /* list header */
705         ret = cli_NetPrintQGetInfo(cli, argv[0], enum_queue, enum_jobs);
706         cli_shutdown(cli);
707         return ret;
708 }
709
710 static int rap_printq_delete(struct net_context *c, int argc, const char **argv)
711 {
712         struct cli_state *cli;
713         int ret;
714
715         if (argc == 0 || c->display_usage)
716                 return net_rap_printq_usage(c, argc, argv);
717
718         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
719                 return -1;
720
721         ret = cli_printjob_del(cli, atoi(argv[0]));
722         cli_shutdown(cli);
723         return ret;
724 }
725
726 int net_rap_printq(struct net_context *c, int argc, const char **argv)
727 {
728         struct cli_state *cli;
729         int ret;
730
731         struct functable func[] = {
732                 {
733                         "info",
734                         rap_printq_info,
735                         NET_TRANSPORT_RAP,
736                         N_("Display info about print queues and jobs"),
737                         N_("net rap printq info [queue]\n"
738                            "    Display info about print jobs in queue.\n"
739                            "    If queue is not specified, all queues are "
740                            "listed")
741                 },
742                 {
743                         "delete",
744                         rap_printq_delete,
745                         NET_TRANSPORT_RAP,
746                         N_("Delete print job(s)"),
747                         N_("net rap printq delete\n"
748                            "    Delete print job(s)")
749                 },
750                 {NULL, NULL, 0, NULL, NULL}
751         };
752
753         if (argc == 0) {
754                 if (c->display_usage) {
755                         d_printf(_("Usage:\n"));
756                         d_printf(_("net rap printq\n"
757                                    "    List the print queue\n"));
758                         net_display_usage_from_functable(func);
759                         return 0;
760                 }
761
762                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
763                         return -1;
764
765                 d_printf(PRINTQ_ENUM_DISPLAY, cli->desthost); /* list header */
766                 ret = cli_NetPrintQEnum(cli, enum_queue, enum_jobs);
767                 cli_shutdown(cli);
768                 return ret;
769         }
770
771         return net_run_function(c, argc, argv, "net rap printq", func);
772 }
773
774 static int net_rap_user_usage(struct net_context *c, int argc, const char **argv)
775 {
776         return net_user_usage(c, argc, argv);
777 }
778
779 static void user_fn(const char *user_name, void *state)
780 {
781         d_printf("%-21.21s\n", user_name);
782 }
783
784 static void long_user_fn(const char *user_name, const char *comment,
785                          const char * home_dir, const char * logon_script,
786                          void *state)
787 {
788         d_printf("%-21.21s %s\n",
789                  user_name, comment);
790 }
791
792 static void group_member_fn(const char *user_name, void *state)
793 {
794         d_printf("%-21.21s\n", user_name);
795 }
796
797 static int rap_user_delete(struct net_context *c, int argc, const char **argv)
798 {
799         struct cli_state *cli;
800         int ret;
801
802         if (argc == 0 || c->display_usage) {
803                 return net_rap_user_usage(c, argc, argv);
804         }
805
806         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
807                 return -1;
808
809         ret = cli_NetUserDelete(cli, argv[0]);
810         cli_shutdown(cli);
811         return ret;
812 }
813
814 static int rap_user_add(struct net_context *c, int argc, const char **argv)
815 {
816         struct cli_state *cli;
817         int ret;
818         struct rap_user_info_1 userinfo;
819
820         if (argc == 0 || c->display_usage) {
821                 return net_rap_user_usage(c, argc, argv);
822         }
823
824         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
825                 return -1;
826
827         safe_strcpy((char *)userinfo.user_name, argv[0], sizeof(userinfo.user_name)-1);
828         if (c->opt_flags == 0)
829                 c->opt_flags = 0x21;
830
831         userinfo.userflags = c->opt_flags;
832         userinfo.reserved1 = '\0';
833         userinfo.comment = smb_xstrdup(c->opt_comment ? c->opt_comment : "");
834         userinfo.priv = 1;
835         userinfo.home_dir = NULL;
836         userinfo.logon_script = NULL;
837         userinfo.passwrd[0] = '\0';
838
839         ret = cli_NetUserAdd(cli, &userinfo);
840
841         cli_shutdown(cli);
842         return ret;
843 }
844
845 static int rap_user_info(struct net_context *c, int argc, const char **argv)
846 {
847         struct cli_state *cli;
848         int ret;
849         if (argc == 0 || c->display_usage) {
850                 return net_rap_user_usage(c, argc, argv);
851         }
852
853         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
854                 return -1;
855
856         ret = cli_NetUserGetGroups(cli, argv[0], group_member_fn, NULL);
857         cli_shutdown(cli);
858         return ret;
859 }
860
861 int net_rap_user(struct net_context *c, int argc, const char **argv)
862 {
863         int ret = -1;
864         struct functable func[] = {
865                 {
866                         "add",
867                         rap_user_add,
868                         NET_TRANSPORT_RAP,
869                         N_("Add specified user"),
870                         N_("net rap user add\n"
871                            "    Add specified user")
872                 },
873                 {
874                         "info",
875                         rap_user_info,
876                         NET_TRANSPORT_RAP,
877                         N_("List domain groups of specified user"),
878                         N_("net rap user info\n"
879                            "    List domain groups of specified user")
880
881                 },
882                 {
883                         "delete",
884                         rap_user_delete,
885                         NET_TRANSPORT_RAP,
886                         N_("Remove specified user"),
887                         N_("net rap user delete\n"
888                            "    Remove specified user")
889                 },
890                 {NULL, NULL, 0, NULL, NULL}
891         };
892
893         if (argc == 0) {
894                 struct cli_state *cli;
895                 if (c->display_usage) {
896                         d_printf(_("Usage:\n"));
897                         d_printf(_("net rap user\n"
898                                    "    List all users\n"));
899                         net_display_usage_from_functable(func);
900                         return 0;
901                 }
902
903                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
904                         goto done;
905                 if (c->opt_long_list_entries) {
906                         d_printf(_("\nUser name             Comment"
907                                    "\n-----------------------------\n"));
908                         ret = cli_RNetUserEnum(cli, long_user_fn, NULL);
909                         cli_shutdown(cli);
910                         goto done;
911                 }
912                 ret = cli_RNetUserEnum0(cli, user_fn, NULL);
913                 cli_shutdown(cli);
914                 goto done;
915         }
916
917         ret = net_run_function(c, argc, argv, "net rap user", func);
918  done:
919         if (ret != 0) {
920                 DEBUG(1, (_("Net user returned: %d\n"), ret));
921         }
922         return ret;
923 }
924
925
926 int net_rap_group_usage(struct net_context *c, int argc, const char **argv)
927 {
928         return net_group_usage(c, argc, argv);
929 }
930
931 static void long_group_fn(const char *group_name, const char *comment,
932                           void *state)
933 {
934         d_printf("%-21.21s %s\n", group_name, comment);
935 }
936
937 static void group_fn(const char *group_name, void *state)
938 {
939         d_printf("%-21.21s\n", group_name);
940 }
941
942 static int rap_group_delete(struct net_context *c, int argc, const char **argv)
943 {
944         struct cli_state *cli;
945         int ret;
946         if (argc == 0 || c->display_usage) {
947                 return net_rap_group_usage(c, argc, argv);
948         }
949
950         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
951                 return -1;
952
953         ret = cli_NetGroupDelete(cli, argv[0]);
954         cli_shutdown(cli);
955         return ret;
956 }
957
958 static int rap_group_add(struct net_context *c, int argc, const char **argv)
959 {
960         struct cli_state *cli;
961         int ret;
962         struct rap_group_info_1 grinfo;
963
964         if (argc == 0 || c->display_usage) {
965                 return net_rap_group_usage(c, argc, argv);
966         }
967
968         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
969                 return -1;
970
971         /* BB check for length 21 or smaller explicitly ? BB */
972         safe_strcpy((char *)grinfo.group_name, argv[0], sizeof(grinfo.group_name)-1);
973         grinfo.reserved1 = '\0';
974         grinfo.comment = smb_xstrdup(c->opt_comment ? c->opt_comment : "");
975
976         ret = cli_NetGroupAdd(cli, &grinfo);
977         cli_shutdown(cli);
978         return ret;
979 }
980
981 int net_rap_group(struct net_context *c, int argc, const char **argv)
982 {
983         struct functable func[] = {
984                 {
985                         "add",
986                         rap_group_add,
987                         NET_TRANSPORT_RAP,
988                         N_("Add specified group"),
989                         N_("net rap group add\n"
990                            "    Add specified group")
991                 },
992                 {
993                         "delete",
994                         rap_group_delete,
995                         NET_TRANSPORT_RAP,
996                         N_("Delete specified group"),
997                         N_("net rap group delete\n"
998                            "    Delete specified group")
999                 },
1000                 {NULL, NULL, 0, NULL, NULL}
1001         };
1002
1003         if (argc == 0) {
1004                 struct cli_state *cli;
1005                 int ret;
1006                 if (c->display_usage) {
1007                         d_printf(_("Usage:\n"));
1008                         d_printf(_("net rap group\n"
1009                                    "    List all groups\n"));
1010                         net_display_usage_from_functable(func);
1011                         return 0;
1012                 }
1013
1014                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1015                         return -1;
1016                 if (c->opt_long_list_entries) {
1017                         d_printf(_("Group name            Comment\n"
1018                                    "-----------------------------\n"));
1019                         ret = cli_RNetGroupEnum(cli, long_group_fn, NULL);
1020                         cli_shutdown(cli);
1021                         return ret;
1022                 }
1023                 ret = cli_RNetGroupEnum0(cli, group_fn, NULL);
1024                 cli_shutdown(cli);
1025                 return ret;
1026         }
1027
1028         return net_run_function(c, argc, argv, "net rap group", func);
1029 }
1030
1031 int net_rap_groupmember_usage(struct net_context *c, int argc, const char **argv)
1032 {
1033         d_printf(_(
1034          "net rap groupmember LIST <group> [misc. options] [targets]"
1035          "\n\t Enumerate users in a group\n"
1036          "\nnet rap groupmember DELETE <group> <user> [misc. options] "
1037          "[targets]\n\t Delete specified user from specified group\n"
1038          "\nnet rap groupmember ADD <group> <user> [misc. options] [targets]"
1039          "\n\t Add specified user to specified group\n"));
1040
1041         net_common_flags_usage(c, argc, argv);
1042         return -1;
1043 }
1044
1045
1046 static int rap_groupmember_add(struct net_context *c, int argc, const char **argv)
1047 {
1048         struct cli_state *cli;
1049         int ret;
1050         if (argc != 2 || c->display_usage) {
1051                 return net_rap_groupmember_usage(c, argc, argv);
1052         }
1053
1054         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1055                 return -1;
1056
1057         ret = cli_NetGroupAddUser(cli, argv[0], argv[1]);
1058         cli_shutdown(cli);
1059         return ret;
1060 }
1061
1062 static int rap_groupmember_delete(struct net_context *c, int argc, const char **argv)
1063 {
1064         struct cli_state *cli;
1065         int ret;
1066         if (argc != 2 || c->display_usage) {
1067                 return net_rap_groupmember_usage(c, argc, argv);
1068         }
1069
1070         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1071                 return -1;
1072
1073         ret = cli_NetGroupDelUser(cli, argv[0], argv[1]);
1074         cli_shutdown(cli);
1075         return ret;
1076 }
1077
1078 static int rap_groupmember_list(struct net_context *c, int argc, const char **argv)
1079 {
1080         struct cli_state *cli;
1081         int ret;
1082         if (argc == 0 || c->display_usage) {
1083                 return net_rap_groupmember_usage(c, argc, argv);
1084         }
1085
1086         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1087                 return -1;
1088
1089         ret = cli_NetGroupGetUsers(cli, argv[0], group_member_fn, NULL );
1090         cli_shutdown(cli);
1091         return ret;
1092 }
1093
1094 int net_rap_groupmember(struct net_context *c, int argc, const char **argv)
1095 {
1096         struct functable func[] = {
1097                 {
1098                         "add",
1099                         rap_groupmember_add,
1100                         NET_TRANSPORT_RAP,
1101                         N_("Add specified user to group"),
1102                         N_("net rap groupmember add\n"
1103                            "    Add specified user to group")
1104                 },
1105                 {
1106                         "list",
1107                         rap_groupmember_list,
1108                         NET_TRANSPORT_RAP,
1109                         N_("List users in group"),
1110                         N_("net rap groupmember list\n"
1111                            "    List users in group")
1112                 },
1113                 {
1114                         "delete",
1115                         rap_groupmember_delete,
1116                         NET_TRANSPORT_RAP,
1117                         N_("Remove user from group"),
1118                         N_("net rap groupmember delete\n"
1119                            "    Remove user from group")
1120                 },
1121                 {NULL, NULL, 0, NULL, NULL}
1122         };
1123
1124         return net_run_function(c, argc, argv, "net rap groupmember", func);
1125 }
1126
1127 int net_rap_validate_usage(struct net_context *c, int argc, const char **argv)
1128 {
1129         d_printf(_("net rap validate <username> [password]\n"
1130                    "\tValidate user and password to check whether they"
1131                    " can access target server or domain\n"));
1132
1133         net_common_flags_usage(c, argc, argv);
1134         return -1;
1135 }
1136
1137 int net_rap_validate(struct net_context *c, int argc, const char **argv)
1138 {
1139         return errmsg_not_implemented();
1140 }
1141
1142 int net_rap_service_usage(struct net_context *c, int argc, const char **argv)
1143 {
1144         d_printf(_("net rap service [misc. options] [targets] \n"
1145                  "\tlists all running service daemons on target server\n"));
1146         d_printf(_("\nnet rap service START <name> [service startup arguments]"
1147                  " [misc. options] [targets]"
1148                  "\n\tStart named service on remote server\n"));
1149         d_printf(_("\nnet rap service STOP <name> [misc. options] [targets]\n"
1150                  "\n\tStop named service on remote server\n"));
1151
1152         net_common_flags_usage(c, argc, argv);
1153         return -1;
1154 }
1155
1156 static int rap_service_start(struct net_context *c, int argc, const char **argv)
1157 {
1158         return errmsg_not_implemented();
1159 }
1160
1161 static int rap_service_stop(struct net_context *c, int argc, const char **argv)
1162 {
1163         return errmsg_not_implemented();
1164 }
1165
1166 static void service_fn(const char *service_name, const char *dummy,
1167                        void *state)
1168 {
1169         d_printf("%-21.21s\n", service_name);
1170 }
1171
1172 int net_rap_service(struct net_context *c, int argc, const char **argv)
1173 {
1174         struct functable func[] = {
1175                 {
1176                         "start",
1177                         rap_service_start,
1178                         NET_TRANSPORT_RAP,
1179                         N_("Start service on remote server"),
1180                         N_("net rap service start\n"
1181                            "    Start service on remote server")
1182                 },
1183                 {
1184                         "stop",
1185                         rap_service_stop,
1186                         NET_TRANSPORT_RAP,
1187                         N_("Stop named serve on remote server"),
1188                         N_("net rap service stop\n"
1189                            "    Stop named serve on remote server")
1190                 },
1191                 {NULL, NULL, 0, NULL, NULL}
1192         };
1193
1194         if (argc == 0) {
1195                 struct cli_state *cli;
1196                 int ret;
1197                 if (c->display_usage) {
1198                         d_printf(_("Usage:\n"));
1199                         d_printf(_("net rap service\n"
1200                                    "    List services on remote server\n"));
1201                         net_display_usage_from_functable(func);
1202                         return 0;
1203                 }
1204
1205                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1206                         return -1;
1207
1208                 if (c->opt_long_list_entries) {
1209                         d_printf(_("Service name          Comment\n"
1210                                    "-----------------------------\n"));
1211                         ret = cli_RNetServiceEnum(cli, long_group_fn, NULL);
1212                 }
1213                 ret = cli_RNetServiceEnum(cli, service_fn, NULL);
1214                 cli_shutdown(cli);
1215                 return ret;
1216         }
1217
1218         return net_run_function(c, argc, argv, "net rap service", func);
1219 }
1220
1221 int net_rap_password_usage(struct net_context *c, int argc, const char **argv)
1222 {
1223         d_printf(_(
1224          "net rap password <user> <oldpwo> <newpw> [misc. options] [target]\n"
1225          "\tchanges the password for the specified user at target\n"));
1226
1227         return -1;
1228 }
1229
1230
1231 int net_rap_password(struct net_context *c, int argc, const char **argv)
1232 {
1233         struct cli_state *cli;
1234         int ret;
1235
1236         if (argc < 3 || c->display_usage)
1237                 return net_rap_password_usage(c, argc, argv);
1238
1239         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1240                 return -1;
1241
1242         /* BB Add check for password lengths? */
1243         ret = cli_oem_change_password(cli, argv[0], argv[2], argv[1]);
1244         cli_shutdown(cli);
1245         return ret;
1246 }
1247
1248 int net_rap_admin_usage(struct net_context *c, int argc, const char **argv)
1249 {
1250         d_printf(_(
1251    "net rap admin <remote command> [cmd args [env]] [misc. options] [targets]"
1252    "\n\texecutes a remote command on an os/2 target server\n"));
1253
1254         return -1;
1255 }
1256
1257
1258 int net_rap_admin(struct net_context *c, int argc, const char **argv)
1259 {
1260         return errmsg_not_implemented();
1261 }
1262
1263 /* Entry-point for all the RAP functions. */
1264
1265 int net_rap(struct net_context *c, int argc, const char **argv)
1266 {
1267         struct functable func[] = {
1268                 {
1269                         "file",
1270                         net_rap_file,
1271                         NET_TRANSPORT_RAP,
1272                         N_("List open files"),
1273                         N_("net rap file\n"
1274                            "    List open files")
1275                 },
1276                 {
1277                         "share",
1278                         net_rap_share,
1279                         NET_TRANSPORT_RAP,
1280                         N_("List shares exported by server"),
1281                         N_("net rap share\n"
1282                            "    List shares exported by server")
1283                 },
1284                 {
1285                         "session",
1286                         net_rap_session,
1287                         NET_TRANSPORT_RAP,
1288                         N_("List open sessions"),
1289                         N_("net rap session\n"
1290                            "    List open sessions")
1291                 },
1292                 {
1293                         "server",
1294                         net_rap_server,
1295                         NET_TRANSPORT_RAP,
1296                         N_("List servers in workgroup"),
1297                         N_("net rap server\n"
1298                            "    List servers in domain/workgroup")
1299                 },
1300                 {
1301                         "domain",
1302                         net_rap_domain,
1303                         NET_TRANSPORT_RAP,
1304                         N_("List domains in network"),
1305                         N_("net rap domain\n"
1306                            "    List domains in network")
1307                 },
1308                 {
1309                         "printq",
1310                         net_rap_printq,
1311                         NET_TRANSPORT_RAP,
1312                         N_("List printer queues on server"),
1313                         N_("net rap printq\n"
1314                            "    List printer queues on server")
1315                 },
1316                 {
1317                         "user",
1318                         net_rap_user,
1319                         NET_TRANSPORT_RAP,
1320                         N_("List users"),
1321                         N_("net rap user\n"
1322                            "    List users")
1323                 },
1324                 {
1325                         "group",
1326                         net_rap_group,
1327                         NET_TRANSPORT_RAP,
1328                         N_("List user groups"),
1329                         N_("net rap group\n"
1330                            "    List user groups")
1331                 },
1332                 {
1333                         "validate",
1334                         net_rap_validate,
1335                         NET_TRANSPORT_RAP,
1336                         N_("Check username/password"),
1337                         N_("net rap validate\n"
1338                            "    Check username/password")
1339                 },
1340                 {
1341                         "groupmember",
1342                         net_rap_groupmember,
1343                         NET_TRANSPORT_RAP,
1344                         N_("List/modify group memberships"),
1345                         N_("net rap groupmember\n"
1346                            "    List/modify group memberships")
1347                 },
1348                 {
1349                         "admin",
1350                         net_rap_admin,
1351                         NET_TRANSPORT_RAP,
1352                         N_("Execute commands on remote OS/2"),
1353                         N_("net rap admin\n"
1354                            "    Execute commands on remote OS/2")
1355                 },
1356                 {
1357                         "service",
1358                         net_rap_service,
1359                         NET_TRANSPORT_RAP,
1360                         N_("Start/stop remote service"),
1361                         N_("net rap service\n"
1362                            "    Start/stop remote service")
1363                 },
1364                 {
1365                         "password",
1366                         net_rap_password,
1367                         NET_TRANSPORT_RAP,
1368                         N_("Change user password"),
1369                         N_("net rap password\n"
1370                            "    Change user password")
1371                 },
1372                 {NULL, NULL, 0, NULL, NULL}
1373         };
1374
1375         return net_run_function(c, argc, argv, "net rap", func);
1376 }
1377