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