Merge branch 'master' of ssh://git.samba.org/data/git/samba
[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);
826         userinfo.priv = 1;
827         userinfo.home_dir = NULL;
828         userinfo.logon_script = NULL;
829
830         ret = cli_NetUserAdd(cli, &userinfo);
831
832         cli_shutdown(cli);
833         return ret;
834 }
835
836 static int rap_user_info(struct net_context *c, int argc, const char **argv)
837 {
838         struct cli_state *cli;
839         int ret;
840         if (argc == 0 || c->display_usage) {
841                 return net_rap_user_usage(c, argc, argv);
842         }
843
844         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
845                 return -1;
846
847         ret = cli_NetUserGetGroups(cli, argv[0], group_member_fn, NULL);
848         cli_shutdown(cli);
849         return ret;
850 }
851
852 int net_rap_user(struct net_context *c, int argc, const char **argv)
853 {
854         int ret = -1;
855         struct functable func[] = {
856                 {
857                         "add",
858                         rap_user_add,
859                         NET_TRANSPORT_RAP,
860                         "Add specified user",
861                         "net rap user add\n"
862                         "    Add specified user"
863                 },
864                 {
865                         "info",
866                         rap_user_info,
867                         NET_TRANSPORT_RAP,
868                         "List domain groups of specified user",
869                         "net rap user info\n"
870                         "    List domain groups of specified user"
871
872                 },
873                 {
874                         "delete",
875                         rap_user_delete,
876                         NET_TRANSPORT_RAP,
877                         "Remove specified user",
878                         "net rap user delete\n"
879                         "    Remove specified user"
880                 },
881                 {NULL, NULL, 0, NULL, NULL}
882         };
883
884         if (argc == 0) {
885                 struct cli_state *cli;
886                 if (c->display_usage) {
887                         d_printf("Usage:\n");
888                         d_printf("net rap user\n"
889                                  "    List all users\n");
890                         net_display_usage_from_functable(func);
891                         return 0;
892                 }
893
894                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
895                         goto done;
896                 if (c->opt_long_list_entries) {
897                         d_printf("\nUser name             Comment"
898                                  "\n-----------------------------\n");
899                         ret = cli_RNetUserEnum(cli, long_user_fn, NULL);
900                         cli_shutdown(cli);
901                         goto done;
902                 }
903                 ret = cli_RNetUserEnum0(cli, user_fn, NULL);
904                 cli_shutdown(cli);
905                 goto done;
906         }
907
908         ret = net_run_function(c, argc, argv, "net rap user", func);
909  done:
910         if (ret != 0) {
911                 DEBUG(1, ("Net user returned: %d\n", ret));
912         }
913         return ret;
914 }
915
916
917 int net_rap_group_usage(struct net_context *c, int argc, const char **argv)
918 {
919         return net_group_usage(c, argc, argv);
920 }
921
922 static void long_group_fn(const char *group_name, const char *comment,
923                           void *state)
924 {
925         d_printf("%-21.21s %s\n", group_name, comment);
926 }
927
928 static void group_fn(const char *group_name, void *state)
929 {
930         d_printf("%-21.21s\n", group_name);
931 }
932
933 static int rap_group_delete(struct net_context *c, int argc, const char **argv)
934 {
935         struct cli_state *cli;
936         int ret;
937         if (argc == 0 || c->display_usage) {
938                 return net_rap_group_usage(c, argc, argv);
939         }
940
941         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
942                 return -1;
943
944         ret = cli_NetGroupDelete(cli, argv[0]);
945         cli_shutdown(cli);
946         return ret;
947 }
948
949 static int rap_group_add(struct net_context *c, int argc, const char **argv)
950 {
951         struct cli_state *cli;
952         int ret;
953         RAP_GROUP_INFO_1 grinfo;
954
955         if (argc == 0 || c->display_usage) {
956                 return net_rap_group_usage(c, argc, argv);
957         }
958
959         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
960                 return -1;
961
962         /* BB check for length 21 or smaller explicitly ? BB */
963         safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name)-1);
964         grinfo.reserved1 = '\0';
965         grinfo.comment = smb_xstrdup(c->opt_comment);
966
967         ret = cli_NetGroupAdd(cli, &grinfo);
968         cli_shutdown(cli);
969         return ret;
970 }
971
972 int net_rap_group(struct net_context *c, int argc, const char **argv)
973 {
974         struct functable func[] = {
975                 {
976                         "add",
977                         rap_group_add,
978                         NET_TRANSPORT_RAP,
979                         "Add specified group",
980                         "net rap group add\n"
981                         "    Add specified group"
982                 },
983                 {
984                         "delete",
985                         rap_group_delete,
986                         NET_TRANSPORT_RAP,
987                         "Delete specified group",
988                         "net rap group delete\n"
989                         "    Delete specified group"
990                 },
991                 {NULL, NULL, 0, NULL, NULL}
992         };
993
994         if (argc == 0) {
995                 struct cli_state *cli;
996                 int ret;
997                 if (c->display_usage) {
998                         d_printf("Usage:\n");
999                         d_printf("net rap group\n"
1000                                  "    List all groups\n");
1001                         net_display_usage_from_functable(func);
1002                         return 0;
1003                 }
1004
1005                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1006                         return -1;
1007                 if (c->opt_long_list_entries) {
1008                         d_printf("Group name            Comment\n");
1009                         d_printf("-----------------------------\n");
1010                         ret = cli_RNetGroupEnum(cli, long_group_fn, NULL);
1011                         cli_shutdown(cli);
1012                         return ret;
1013                 }
1014                 ret = cli_RNetGroupEnum0(cli, group_fn, NULL);
1015                 cli_shutdown(cli);
1016                 return ret;
1017         }
1018
1019         return net_run_function(c, argc, argv, "net rap group", func);
1020 }
1021
1022 int net_rap_groupmember_usage(struct net_context *c, int argc, const char **argv)
1023 {
1024         d_printf(
1025          "net rap groupmember LIST <group> [misc. options] [targets]"
1026          "\n\t Enumerate users in a group\n"
1027          "\nnet rap groupmember DELETE <group> <user> [misc. options] "
1028          "[targets]\n\t Delete specified user from specified group\n"
1029          "\nnet rap groupmember ADD <group> <user> [misc. options] [targets]"
1030          "\n\t Add specified user to specified group\n");
1031
1032         net_common_flags_usage(c, argc, argv);
1033         return -1;
1034 }
1035
1036
1037 static int rap_groupmember_add(struct net_context *c, int argc, const char **argv)
1038 {
1039         struct cli_state *cli;
1040         int ret;
1041         if (argc != 2 || c->display_usage) {
1042                 return net_rap_groupmember_usage(c, argc, argv);
1043         }
1044
1045         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1046                 return -1;
1047
1048         ret = cli_NetGroupAddUser(cli, argv[0], argv[1]);
1049         cli_shutdown(cli);
1050         return ret;
1051 }
1052
1053 static int rap_groupmember_delete(struct net_context *c, int argc, const char **argv)
1054 {
1055         struct cli_state *cli;
1056         int ret;
1057         if (argc != 2 || c->display_usage) {
1058                 return net_rap_groupmember_usage(c, argc, argv);
1059         }
1060
1061         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1062                 return -1;
1063
1064         ret = cli_NetGroupDelUser(cli, argv[0], argv[1]);
1065         cli_shutdown(cli);
1066         return ret;
1067 }
1068
1069 static int rap_groupmember_list(struct net_context *c, int argc, const char **argv)
1070 {
1071         struct cli_state *cli;
1072         int ret;
1073         if (argc == 0 || c->display_usage) {
1074                 return net_rap_groupmember_usage(c, argc, argv);
1075         }
1076
1077         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1078                 return -1;
1079
1080         ret = cli_NetGroupGetUsers(cli, argv[0], group_member_fn, NULL );
1081         cli_shutdown(cli);
1082         return ret;
1083 }
1084
1085 int net_rap_groupmember(struct net_context *c, int argc, const char **argv)
1086 {
1087         struct functable func[] = {
1088                 {
1089                         "add",
1090                         rap_groupmember_add,
1091                         NET_TRANSPORT_RAP,
1092                         "Add specified user to group",
1093                         "net rap groupmember add\n"
1094                         "    Add specified user to group"
1095                 },
1096                 {
1097                         "list",
1098                         rap_groupmember_list,
1099                         NET_TRANSPORT_RAP,
1100                         "List users in group",
1101                         "net rap groupmember list\n"
1102                         "    List users in group"
1103                 },
1104                 {
1105                         "delete",
1106                         rap_groupmember_delete,
1107                         NET_TRANSPORT_RAP,
1108                         "Remove user from group",
1109                         "net rap groupmember delete\n"
1110                         "    Remove user from group"
1111                 },
1112                 {NULL, NULL, 0, NULL, NULL}
1113         };
1114
1115         return net_run_function(c, argc, argv, "net rap groupmember", func);
1116 }
1117
1118 int net_rap_validate_usage(struct net_context *c, int argc, const char **argv)
1119 {
1120         d_printf("net rap validate <username> [password]\n"
1121                  "\tValidate user and password to check whether they"
1122                  " can access target server or domain\n");
1123
1124         net_common_flags_usage(c, argc, argv);
1125         return -1;
1126 }
1127
1128 int net_rap_validate(struct net_context *c, int argc, const char **argv)
1129 {
1130         return errmsg_not_implemented();
1131 }
1132
1133 int net_rap_service_usage(struct net_context *c, int argc, const char **argv)
1134 {
1135         d_printf("net rap service [misc. options] [targets] \n"
1136                  "\tlists all running service daemons on target server\n");
1137         d_printf("\nnet rap service START <name> [service startup arguments]"
1138                  " [misc. options] [targets]"
1139                  "\n\tStart named service on remote server\n");
1140         d_printf("\nnet rap service STOP <name> [misc. options] [targets]\n"
1141                  "\n\tStop named service on remote server\n");
1142
1143         net_common_flags_usage(c, argc, argv);
1144         return -1;
1145 }
1146
1147 static int rap_service_start(struct net_context *c, int argc, const char **argv)
1148 {
1149         return errmsg_not_implemented();
1150 }
1151
1152 static int rap_service_stop(struct net_context *c, int argc, const char **argv)
1153 {
1154         return errmsg_not_implemented();
1155 }
1156
1157 static void service_fn(const char *service_name, const char *dummy,
1158                        void *state)
1159 {
1160         d_printf("%-21.21s\n", service_name);
1161 }
1162
1163 int net_rap_service(struct net_context *c, int argc, const char **argv)
1164 {
1165         struct functable func[] = {
1166                 {
1167                         "start",
1168                         rap_service_start,
1169                         NET_TRANSPORT_RAP,
1170                         "Start service on remote server",
1171                         "net rap service start\n"
1172                         "    Start service on remote server"
1173                 },
1174                 {
1175                         "stop",
1176                         rap_service_stop,
1177                         NET_TRANSPORT_RAP,
1178                         "Stop named serve on remote server",
1179                         "net rap service stop\n"
1180                         "    Stop named serve on remote server"
1181                 },
1182                 {NULL, NULL, 0, NULL, NULL}
1183         };
1184
1185         if (argc == 0) {
1186                 struct cli_state *cli;
1187                 int ret;
1188                 if (c->display_usage) {
1189                         d_printf("Usage:\n");
1190                         d_printf("net rap service\n"
1191                                  "    List services on remote server\n");
1192                         net_display_usage_from_functable(func);
1193                         return 0;
1194                 }
1195
1196                 if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1197                         return -1;
1198
1199                 if (c->opt_long_list_entries) {
1200                         d_printf("Service name          Comment\n");
1201                         d_printf("-----------------------------\n");
1202                         ret = cli_RNetServiceEnum(cli, long_group_fn, NULL);
1203                 }
1204                 ret = cli_RNetServiceEnum(cli, service_fn, NULL);
1205                 cli_shutdown(cli);
1206                 return ret;
1207         }
1208
1209         return net_run_function(c, argc, argv, "net rap service", func);
1210 }
1211
1212 int net_rap_password_usage(struct net_context *c, int argc, const char **argv)
1213 {
1214         d_printf(
1215          "net rap password <user> <oldpwo> <newpw> [misc. options] [target]\n"
1216          "\tchanges the password for the specified user at target\n");
1217
1218         return -1;
1219 }
1220
1221
1222 int net_rap_password(struct net_context *c, int argc, const char **argv)
1223 {
1224         struct cli_state *cli;
1225         int ret;
1226
1227         if (argc < 3 || c->display_usage)
1228                 return net_rap_password_usage(c, argc, argv);
1229
1230         if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
1231                 return -1;
1232
1233         /* BB Add check for password lengths? */
1234         ret = cli_oem_change_password(cli, argv[0], argv[2], argv[1]);
1235         cli_shutdown(cli);
1236         return ret;
1237 }
1238
1239 int net_rap_admin_usage(struct net_context *c, int argc, const char **argv)
1240 {
1241         d_printf(
1242    "net rap admin <remote command> [cmd args [env]] [misc. options] [targets]"
1243    "\n\texecutes a remote command on an os/2 target server\n");
1244
1245         return -1;
1246 }
1247
1248
1249 int net_rap_admin(struct net_context *c, int argc, const char **argv)
1250 {
1251         return errmsg_not_implemented();
1252 }
1253
1254 /* Entry-point for all the RAP functions. */
1255
1256 int net_rap(struct net_context *c, int argc, const char **argv)
1257 {
1258         struct functable func[] = {
1259                 {
1260                         "file",
1261                         net_rap_file,
1262                         NET_TRANSPORT_RAP,
1263                         "List open files",
1264                         "net rap file\n"
1265                         "    List open files"
1266                 },
1267                 {
1268                         "share",
1269                         net_rap_share,
1270                         NET_TRANSPORT_RAP,
1271                         "List shares exported by server",
1272                         "net rap share\n"
1273                         "    List shares exported by server"
1274                 },
1275                 {
1276                         "session",
1277                         net_rap_session,
1278                         NET_TRANSPORT_RAP,
1279                         "List open sessions",
1280                         "net rap session\n"
1281                         "    List open sessions"
1282                 },
1283                 {
1284                         "server",
1285                         net_rap_server,
1286                         NET_TRANSPORT_RAP,
1287                         "List servers in workgroup",
1288                         "net rap server\n"
1289                         "    List servers in domain/workgroup"
1290                 },
1291                 {
1292                         "domain",
1293                         net_rap_domain,
1294                         NET_TRANSPORT_RAP,
1295                         "List domains in network",
1296                         "net rap domain\n"
1297                         "    List domains in network"
1298                 },
1299                 {
1300                         "printq",
1301                         net_rap_printq,
1302                         NET_TRANSPORT_RAP,
1303                         "List printer queues on server",
1304                         "net rap printq\n"
1305                         "    List printer queues on server"
1306                 },
1307                 {
1308                         "user",
1309                         net_rap_user,
1310                         NET_TRANSPORT_RAP,
1311                         "List users",
1312                         "net rap user\n"
1313                         "    List users"
1314                 },
1315                 {
1316                         "group",
1317                         net_rap_group,
1318                         NET_TRANSPORT_RAP,
1319                         "List user groups",
1320                         "net rap group\n"
1321                         "    List user groups"
1322                 },
1323                 {
1324                         "validate",
1325                         net_rap_validate,
1326                         NET_TRANSPORT_RAP,
1327                         "Check username/password",
1328                         "net rap validate\n"
1329                         "    Check username/password"
1330                 },
1331                 {
1332                         "groupmember",
1333                         net_rap_groupmember,
1334                         NET_TRANSPORT_RAP,
1335                         "List/modify group memberships",
1336                         "net rap groupmember\n"
1337                         "    List/modify group memberships"
1338                 },
1339                 {
1340                         "admin",
1341                         net_rap_admin,
1342                         NET_TRANSPORT_RAP,
1343                         "Execute commands on remote OS/2",
1344                         "net rap admin\n"
1345                         "    Execute commands on remote OS/2"
1346                 },
1347                 {
1348                         "service",
1349                         net_rap_service,
1350                         NET_TRANSPORT_RAP,
1351                         "Start/stop remote service",
1352                         "net rap service\n"
1353                         "    Start/stop remote service"
1354                 },
1355                 {
1356                         "password",
1357                         net_rap_password,
1358                         NET_TRANSPORT_RAP,
1359                         "Change user password",
1360                         "net rap password\n"
1361                         "    Change user password"
1362                 },
1363                 {NULL, NULL, 0, NULL, NULL}
1364         };
1365
1366         return net_run_function(c, argc, argv, "net rap", func);
1367 }
1368