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