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