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