More help/messages/formatting cleanup.
[samba.git] / source3 / utils / net_rap.c
1 /* 
2    Samba Unix/Linux SMB client library 
3    Version 3.0
4    Distributed SMB/CIFS Server Management Utility 
5    Copyright (C) 2001 Steve French  (sfrench@us.ibm.com)
6    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
7    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
8    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
9
10    Originally written by Steve and Jim. Largely rewritten by tridge in
11    November 2001.
12
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17    
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22    
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
26
27 #include "includes.h"
28 #include "../utils/net.h"
29
30 /* The following messages were for error checking that is not properly 
31    reported at the moment.  Which should be reinstated? */
32 #define ERRMSG_TARGET_WG_NOT_VALID      "\nTarget workgroup option not valid "\
33                                         "except on net rap server command, ignored"
34 #define ERRMSG_INVALID_HELP_OPTION      "\nInvalid help option\n"
35
36 #define ERRMSG_BOTH_SERVER_IPADDRESS    "\nTarget server and IP address both "\
37   "specified. Do not set both at the same time.  The target IP address was used\n"
38
39 static const char *share_type[] = {
40   "Disk",
41   "Print",
42   "Dev",
43   "IPC"
44 };
45
46 static int errmsg_not_implemented(void)
47 {
48         d_printf("\nNot implemented\n");
49         return 0;
50 }
51
52 int general_rap_usage(int argc, const char **argv)
53 {
54
55         d_printf("Valid targets: choose one (none defaults to localhost)\n");
56         d_printf("\t-S or --server=<server>\t\tserver name\n");
57         d_printf("\t-I or --ipaddress=<ipaddr>\taddress of target server\n");
58         d_printf("\t-w or --workgroup=<wg>\t\ttarget workgroup or domain\n");
59
60         d_printf("\n");
61         d_printf("Valid miscellaneous options are:\n"); /* misc options */
62         d_printf("\t-p or --port=<port>\tconnection port on target server\n");
63         d_printf("\t-W or --myworkgroup=<wg>\tclient workgroup\n");
64         d_printf("\t-d or --debug=<level>\t\tdebug level (0-10)\n");
65         d_printf("\t-n or --myname=<name>\t\tclient name\n");
66         d_printf("\t-U or --user=<name>\t\tuser name\n");
67         d_printf("\t-s or --conf=<path>\t\tpathname of smb.conf file\n");
68         d_printf("\t-l or --long\t\t\tDisplay full information\n");
69         return -1;
70 }
71
72
73 int net_rap_file_usage(int argc, const char **argv)
74 {
75         d_printf("net rap file [misc. options] [targets]\n"\
76                  "\tlists all open files on file server\n\n");
77         d_printf("net rap file USER <username> [misc. options] [targets]\n"\
78                  "\tlists all files opened by username on file server\n\n");
79         d_printf("net rap file CLOSE <id> [misc. options] [targets]\n"\
80                  "\tcloses specified file on target server\n");
81
82         general_rap_usage(argc, argv);
83         return -1;
84 }
85
86 /***************************************************************************
87   list info on an open file
88 ***************************************************************************/
89 static void file_fn(const char * pPath, const char * pUser, uint16 perms, 
90                     uint16 locks, uint32 id)
91 {
92         d_printf("\t%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
93                  id, pUser, perms, locks, pPath);
94 }
95
96 static void one_file_fn(const char *pPath, const char *pUser, uint16 perms, 
97                         uint16 locks, uint32 id)
98 {
99         d_printf("File ID          %d\n"\
100                  "User name        %s\n"\
101                  "Locks            0x%-4.2x\n"\
102                  "Path             %s\n"\
103                  "Permissions      0x%x\n",
104                  id, pUser, locks, pPath, perms);
105 }
106
107
108 static int rap_file_close(int argc, const char **argv)
109 {
110         struct cli_state *cli;
111         int ret;
112         if (argc == 0) {
113                 d_printf("\nMissing fileid of file to close\n\n");
114                 return net_rap_file_usage(argc, argv);
115         }
116
117         if (!(cli = net_make_ipc_connection(0))) 
118                 return -1;
119
120         ret = cli_NetFileClose(cli, atoi(argv[0]));
121         cli_shutdown(cli);
122         return ret;
123 }
124
125 static int rap_file_info(int argc, const char **argv)
126 {
127         struct cli_state *cli;
128         int ret;
129         if (argc == 0)
130                 return net_rap_file_usage(argc, argv);
131         
132         if (!(cli = net_make_ipc_connection(0))) 
133                 return -1;
134
135         ret = cli_NetFileGetInfo(cli, atoi(argv[0]), one_file_fn);
136         cli_shutdown(cli);
137         return ret;
138 }
139
140 static int rap_file_user(int argc, const char **argv)
141 {
142         if (argc == 0)
143                 return net_rap_file_usage(argc, argv);
144
145         d_printf("net rap file user not implemented yet\n");
146         return -1;
147 }
148
149 int net_rap_file(int argc, const char **argv)
150 {
151         struct functable func[] = {
152                 {"CLOSE", rap_file_close},
153                 {"USER", rap_file_user},
154                 {"INFO", rap_file_info},
155                 {NULL, NULL}
156         };
157         
158         if (argc == 0) {
159                 struct cli_state *cli;
160                 int ret;
161                 
162                 if (!(cli = net_make_ipc_connection(0))) 
163                         return -1;
164
165                 /* list open files */
166                 d_printf(
167                  "\nEnumerating open files on remote server:\n\n"\
168                  "\n\tFileId  Opened by            Perms  Locks  Path \n"\
169                  "\t------  ---------            -----  -----  ---- \n");
170                 ret = cli_NetFileEnum(cli, NULL, NULL, file_fn);
171                 cli_shutdown(cli);
172                 return ret;
173         }
174         
175         return net_run_function(argc, argv, func, net_rap_file_usage);
176 }
177                        
178 int net_rap_share_usage(int argc, const char **argv)
179 {
180         d_printf(
181          "\nnet [rap] share [misc. options] [targets] \n"\
182          "\tenumerates all exported resources (network shares) "\
183          "on target server\n");
184         d_printf(
185          "\nnet rap share ADD <name=serverpath> [misc. options] [targets]"\
186          "\n\tAdds a share from a server (makes the export active)\n");
187         d_printf(
188          "\nnet rap share DELETE <sharename> [misc. options] [targets]\n"\
189          "\tor"\
190          "\nnet rap share CLOSE <sharename> [misc. options] [targets]"\
191          "\n\tDeletes a share from a server (makes the export inactive)\n");
192         general_rap_usage(argc, argv);
193         d_printf(
194          "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
195         d_printf("\t-M or --maxusers=<num>\t\tmax users allowed for share\n");
196         return -1;
197 }
198
199 static void long_share_fn(const char *share_name, uint32 type, 
200                           const char *comment, void *state)
201 {
202         d_printf("%-12.12s %-8.8s %-50.50s\n",
203                  share_name, share_type[type], comment);
204 }
205
206 static void share_fn(const char *share_name, uint32 type, 
207                      const char *comment, void *state)
208 {
209         d_printf("%-12.12s\n", share_name);
210 }
211
212 static int rap_share_delete(int argc, const char **argv)
213 {
214         struct cli_state *cli;
215         int ret;
216         
217         if (argc == 0) {
218                 d_printf("\n\nShare name not specified\n");
219                 return net_rap_share_usage(argc, argv);
220         }
221
222         if (!(cli = net_make_ipc_connection(0))) 
223                 return -1;
224
225         ret = cli_NetShareDelete(cli, argv[0]);
226         cli_shutdown(cli);
227         return ret;
228 }
229
230 static int rap_share_add(int argc, const char **argv)
231 {
232         struct cli_state *cli;
233         int ret;
234         
235         RAP_SHARE_INFO_2 sinfo;
236         char *p;
237         char *sharename;
238
239         if (argc == 0) {
240                 d_printf("\n\nShare name not specified\n");
241                 return net_rap_share_usage(argc, argv);
242         }
243                         
244         if (!(cli = net_make_ipc_connection(0))) 
245                 return -1;
246
247         sharename = strdup(argv[0]);
248         p = strchr(sharename, '=');
249         *p = 0;
250         strlcpy(sinfo.share_name, sharename, sizeof(sinfo.share_name));
251         sinfo.reserved1 = '\0';
252         sinfo.share_type = 0;
253         sinfo.comment = opt_comment;
254         sinfo.perms = 0;
255         sinfo.maximum_users = opt_maxusers;
256         sinfo.active_users = 0;
257         sinfo.path = p+1;
258         memset(sinfo.password, '\0', sizeof(sinfo.password));
259         sinfo.reserved2 = '\0';
260         
261         ret = cli_NetShareAdd(cli, &sinfo);
262         cli_shutdown(cli);
263         return ret;
264 }
265
266
267 int net_rap_share(int argc, const char **argv)
268 {
269         struct functable func[] = {
270                 {"DELETE", rap_share_delete},
271                 {"CLOSE", rap_share_delete},
272                 {"ADD", rap_share_add},
273                 {NULL, NULL}
274         };
275
276         if (argc == 0) {
277                 struct cli_state *cli;
278                 int ret;
279                 
280                 if (!(cli = net_make_ipc_connection(0))) 
281                         return -1;
282                 
283                 if (opt_long_list_entries) {
284                         d_printf(
285         "\nEnumerating shared resources (exports) on remote server:\n\n"\
286         "\nShare name   Type     Description\n"\
287         "----------   ----     -----------\n");
288                         ret = cli_RNetShareEnum(cli, long_share_fn, NULL);
289                 }
290                 ret = cli_RNetShareEnum(cli, share_fn, NULL);
291                 cli_shutdown(cli);
292                 return ret;
293         }
294
295         return net_run_function(argc, argv, func, net_rap_share_usage);
296 }
297                     
298                 
299 int net_rap_session_usage(int argc, const char **argv)
300 {
301         d_printf(
302          "\nnet rap session [misc. options] [targets]"\
303          "\n\tenumerates all active SMB/CIFS sessions on target server\n");
304         d_printf(
305          "\nnet rap session DELETE <client_name> [misc. options] [targets] \n"\
306          "\tor"\
307          "\nnet rap session CLOSE <client_name> [misc. options] [targets]"\
308          "\n\tDeletes (closes) a session from specified client to server\n");
309
310         general_rap_usage(argc, argv);
311         return -1;
312 }
313     
314 static void list_sessions_func(char *wsname, char *username, uint16 conns,
315                         uint16 opens, uint16 users, uint32 sess_time,
316                         uint32 idle_time, uint32 user_flags, char *clitype)
317 {
318         int hrs = idle_time / 3600;
319         int min = (idle_time / 60) % 60;
320         int sec = idle_time % 60;
321         
322         d_printf("\\\\%-18.18s %-20.20s %-18.18s %5d %2.2d:%2.2d:%2.2d\n",
323                  wsname, username, clitype, opens, hrs, min, sec);
324 }
325
326 static void display_session_func(const char *wsname, const char *username, 
327                                  uint16 conns, uint16 opens, uint16 users, 
328                                  uint32 sess_time, uint32 idle_time, 
329                                  uint32 user_flags, const char *clitype)
330 {
331         int ihrs = idle_time / 3600;
332         int imin = (idle_time / 60) % 60;
333         int isec = idle_time % 60;
334         int shrs = sess_time / 3600;
335         int smin = (sess_time / 60) % 60;
336         int ssec = sess_time % 60;
337         d_printf("User name       %-20.20s\n"\
338                  "Computer        %-20.20s\n"\
339                  "Guest logon     %-20.20s\n"\
340                  "Client Type     %-40.40s\n"\
341                  "Sess time       %2.2d:%2.2d:%2.2d\n"\
342                  "Idle time       %2.2d:%2.2d:%2.2d\n", 
343                  username, wsname, 
344                  (user_flags&0x0)?"yes":"no", clitype,
345                  shrs, smin, ssec, ihrs, imin, isec);
346 }
347
348 static void display_conns_func(uint16 conn_id, uint16 conn_type, uint16 opens,
349                                uint16 users, uint32 conn_time,
350                                const char *username, const char *netname)
351 {
352         d_printf("%-14.14s %-8.8s %5d\n",
353                  netname, share_type[conn_type], opens);
354 }
355
356 static int rap_session_info(int argc, const char **argv)
357 {
358         const char *sessname;
359         struct cli_state *cli;
360         int ret;
361         
362         if (!(cli = net_make_ipc_connection(0))) 
363                 return -1;
364
365         if (argc == 0) 
366                 return net_rap_session_usage(argc, argv);
367
368         sessname = argv[0];
369
370         ret = cli_NetSessionGetInfo(cli, sessname, display_session_func);
371         if (ret < 0) {
372                 cli_shutdown(cli);
373                 return ret;
374         }
375
376         d_printf("Share name     Type     # Opens\n-------------------------"\
377                  "-----------------------------------------------------\n");
378         ret = cli_NetConnectionEnum(cli, sessname, display_conns_func);
379         cli_shutdown(cli);
380         return ret;
381 }
382
383 static int rap_session_delete(int argc, const char **argv)
384 {
385         struct cli_state *cli;
386         int ret;
387         
388         if (!(cli = net_make_ipc_connection(0))) 
389                 return -1;
390
391         if (argc == 0) 
392                 return net_rap_session_usage(argc, argv);
393
394         ret = cli_NetSessionDel(cli, argv[0]);
395         cli_shutdown(cli);
396         return ret;
397 }
398
399 int net_rap_session(int argc, const char **argv)
400 {
401         struct functable func[] = {
402                 {"INFO", rap_session_info},
403                 {"DELETE", rap_session_delete},
404                 {"CLOSE", rap_session_delete},
405                 {NULL, NULL}
406         };
407
408         if (argc == 0) {
409                 struct cli_state *cli;
410                 int ret;
411                 
412                 if (!(cli = net_make_ipc_connection(0))) 
413                         return -1;
414
415                 d_printf("Computer             User name            "\
416                          "Client Type        Opens Idle time\n"\
417                          "------------------------------------------"\
418                          "------------------------------------\n");
419                 ret = cli_NetSessionEnum(cli, list_sessions_func);
420
421                 cli_shutdown(cli);
422                 return ret;
423         }
424
425         return net_run_function(argc, argv, func, net_rap_session_usage);
426 }
427         
428 /****************************************************************************
429 list a server name
430 ****************************************************************************/
431 static void display_server_func(const char *name, uint32 m,
432                                 const char *comment, void * reserved)
433 {
434         d_printf("\t%-16.16s     %s\n", name, comment);
435 }
436
437
438 int net_rap_server_usage(int argc, const char **argv)
439 {
440         d_printf("net rap server [misc. options] [target]\n\t"\
441                  "lists the servers in the specified domain or workgroup.\n");
442         d_printf("\n\tIf domain is not specified, it uses the current"\
443                  " domain or workgroup as\n\tthe default.\n");
444
445         general_rap_usage(argc, argv);
446         return -1;
447 }
448                     
449 int net_rap_server(int argc, const char **argv)
450 {
451         struct cli_state *cli;
452         int ret;
453         
454         if (!(cli = net_make_ipc_connection(0))) 
455                 return -1;
456
457         d_printf("\nEnumerating servers in this domain or workgroup: \n\n"\
458                  "\tServer name          Server description\n"\
459                  "\t-------------        ----------------------------\n");
460
461         ret = cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, 
462                                 display_server_func,NULL); 
463         cli_shutdown(cli);
464         return ret;     
465 }
466                       
467 int net_rap_domain_usage(int argc, const char **argv)
468 {
469         d_printf("net rap domain [misc. options] [target]\n\tlists the"\
470                  " domains or workgroups visible on the current network\n");
471
472         general_rap_usage(argc, argv);
473         return -1;
474 }
475
476                   
477 int net_rap_domain(int argc, const char **argv)
478 {
479         struct cli_state *cli;
480         int ret;
481         
482         if (!(cli = net_make_ipc_connection(0))) 
483                 return -1;
484
485         d_printf("\nEnumerating domains:\n\n"\
486                  "\tDomain name          Server name of Browse Master\n"\
487                  "\t-------------        ----------------------------\n");
488
489         ret = cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM,
490                                 display_server_func,NULL);      
491         cli_shutdown(cli);
492         return ret;     
493 }
494                       
495 int net_rap_printq_usage(int argc, const char **argv)
496 {
497         d_printf(
498          "net rap printq [misc. options] [targets]\n"\
499          "\tor\n"\
500          "net rap printq list [<queue_name>] [misc. options] [targets]\n"\
501          "\tlists the specified queue and jobs on the target server.\n"\
502          "\tIf the queue name is not specified, all queues are listed.\n\n");
503         d_printf(
504          "net rap printq delete [<queue name>] [misc. options] [targets]\n"\
505          "\tdeletes the specified job number on the target server, or the\n"\
506          "\tprinter queue if no job number is specified\n");
507
508         general_rap_usage(argc, argv);
509         d_printf("\t-j or --jobid=<job id>\t\tjob id\n");
510
511         return -1;
512 }       
513
514 static void enum_queue(const char *queuename, uint16 pri, uint16 start, 
515                        uint16 until, const char *sep, const char *pproc, 
516                        const char *dest, const char *qparms, 
517                        const char *qcomment, uint16 status, uint16 jobcount) 
518 {
519         d_printf("%-17.17s Queue %5d jobs                      ",
520                  queuename, jobcount);
521
522         switch (status) {
523         case 0:
524                 d_printf("*Printer Active*\n");
525                 break;
526         case 1:
527                 d_printf("*Printer Paused*\n");
528                 break;
529         case 2:
530                 d_printf("*Printer error*\n");
531                 break;
532         case 3:
533                 d_printf("*Delete Pending*\n");
534                 break;
535         default:
536                 d_printf("**UNKNOWN STATUS**\n");
537         }
538 }
539
540 static void enum_jobs(uint16 jobid, const char *ownername, 
541                       const char *notifyname, const char *datatype,
542                       const char *jparms, uint16 pos, uint16 status, 
543                       const char *jstatus, uint submitted, uint jobsize, 
544                       const char *comment)
545 {
546         d_printf("     %-23.23s %5d %9d            ",
547                  ownername, jobid, jobsize);
548         switch (status) {
549         case 0:
550                 d_printf("Waiting\n");
551                 break;
552         case 1:
553                 d_printf("Held in queue\n");
554                 break;
555         case 2:
556                 d_printf("Spooling\n");
557                 break;
558         case 3:
559                 d_printf("Printing\n");
560                 break;
561         default:
562                 d_printf("**UNKNOWN STATUS**\n");
563         }
564 }
565
566 #define PRINTQ_ENUM_DISPLAY \
567     "Print queues at \\\\%s\n\n"\
568     "Name                         Job #      Size            Status\n\n"\
569     "------------------------------------------------------------------"\
570     "-------------\n"
571
572 static int rap_printq_info(int argc, const char **argv)
573 {
574         struct cli_state *cli;
575         int ret;
576         
577         if (argc == 0) 
578                 return net_rap_printq_usage(argc, argv);
579
580         if (!(cli = net_make_ipc_connection(0))) 
581                 return -1;
582
583         d_printf(PRINTQ_ENUM_DISPLAY, cli->desthost); /* list header */
584         ret = cli_NetPrintQGetInfo(cli, argv[0], enum_queue, enum_jobs);
585         cli_shutdown(cli);
586         return ret;
587 }
588
589 static int rap_printq_delete(int argc, const char **argv)
590 {
591         struct cli_state *cli;
592         int ret;
593         
594         if (argc == 0) 
595                 return net_rap_printq_usage(argc, argv);
596
597         if (!(cli = net_make_ipc_connection(0))) 
598                 return -1;
599
600         ret = cli_printjob_del(cli, atoi(argv[0]));
601         cli_shutdown(cli);
602         return ret;
603 }
604
605 int net_rap_printq(int argc, const char **argv)
606 {
607         struct cli_state *cli;
608         int ret;
609         
610         struct functable func[] = {
611                 {"INFO", rap_printq_info},
612                 {"DELETE", rap_printq_delete},
613                 {NULL, NULL}
614         };
615
616         if (argc == 0) {
617                 if (!(cli = net_make_ipc_connection(0))) 
618                         return -1;
619
620                 d_printf(PRINTQ_ENUM_DISPLAY, cli->desthost); /* list header */
621                 ret = cli_NetPrintQEnum(cli, enum_queue, enum_jobs);
622                 cli_shutdown(cli);
623                 return ret;
624         }
625
626         return net_run_function(argc, argv, func, net_rap_printq_usage);
627 }
628
629         
630 int net_rap_user_usage(int argc, const char **argv)
631 {
632         d_printf("\nnet rap user [misc. options] [targets]\n\tList users\n");
633         d_printf("\nnet rap user DELETE <name> [misc. options] [targets]"\
634                  "\n\tDelete specified user\n");
635         d_printf("\nnet rap user INFO <name> [misc. options] [targets]"\
636                  "\n\tList the domain groups of the specified user\n");
637         d_printf("\nnet rap user ADD <name> [-F user flags] [misc. options]"\
638                  " [targets]\n\tAdd specified user\n");
639
640         general_rap_usage(argc, argv);
641         d_printf(
642          "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
643         return -1;
644
645         
646 static void user_fn(const char *user_name, const char *comment,
647                     const char * home_dir, const char * logon_script,
648                     void *state)
649 {
650         d_printf("%-21.21s\n", user_name);
651 }
652
653 static void long_user_fn(const char *user_name, const char *comment,
654                          const char * home_dir, const char * logon_script, 
655                          void *state)
656 {
657         d_printf("%-21.21s %-47.47s %-35.35s %35.35s\n",
658                  user_name, comment, home_dir, logon_script);
659 }
660
661 static void group_member_fn(const char *user_name, void *state)
662 {
663         d_printf("%-21.21s\n", user_name);
664 }
665
666 static int rap_user_delete(int argc, const char **argv)
667 {
668         struct cli_state *cli;
669         int ret;
670         
671         if (argc == 0) {
672                 d_printf("\n\nUser name not specified\n");
673                 return net_rap_user_usage(argc, argv);
674         }
675
676         if (!(cli = net_make_ipc_connection(0))) 
677                 return -1;
678
679         ret = cli_NetUserDelete(cli, argv[0]);
680         cli_shutdown(cli);
681         return ret;
682 }
683
684 static int rap_user_add(int argc, const char **argv)
685 {
686         struct cli_state *cli;
687         int ret;
688         RAP_USER_INFO_1 userinfo;
689
690         if (argc == 0) {
691                 d_printf("\n\nUser name not specified\n");
692                 return net_rap_user_usage(argc, argv);
693         }
694
695         if (!(cli = net_make_ipc_connection(0)))
696                 return -1;
697                         
698         safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name));
699         if (opt_flags == -1) 
700                 opt_flags = 0x21; 
701                         
702         userinfo.userflags = opt_flags;
703         userinfo.reserved1 = '\0';
704         userinfo.comment = opt_comment;
705         userinfo.priv = 1; 
706         userinfo.home_dir = NULL;
707         userinfo.logon_script = NULL;
708         
709         ret = cli_NetUserAdd(cli, &userinfo);
710         cli_shutdown(cli);
711         return ret;
712 }
713
714 static int rap_user_info(int argc, const char **argv)
715 {
716         struct cli_state *cli;
717         int ret;
718         if (argc == 0) {
719                 d_printf("\n\nUser name not specified\n");
720                 return net_rap_user_usage(argc, argv);
721         }
722
723         if (!(cli = net_make_ipc_connection(0)))
724                 return -1;
725
726         ret = cli_NetUserGetGroups(cli, argv[0], group_member_fn, NULL);
727         cli_shutdown(cli);
728         return ret;
729 }
730
731 int net_rap_user(int argc, const char **argv)
732 {
733         struct functable func[] = {
734                 {"ADD", rap_user_add},
735                 {"INFO", rap_user_info},
736                 {"DELETE", rap_user_delete},
737                 {NULL, NULL}
738         };
739
740         if (argc == 0) {
741                 struct cli_state *cli;
742                 int ret;
743                 if (!(cli = net_make_ipc_connection(0)))
744                         return -1;
745                 if (opt_long_list_entries) {
746                         d_printf(
747    "\nListing users on remote server:\n\n"\
748    "\nUser name             Description                                     "\
749    "Home Directory                          Profile Directory"\
750    "\n---------             -----------                                     "\
751    "--------------                          -----------------\n");
752                         ret = cli_RNetUserEnum(cli, long_user_fn, NULL);
753                         cli_shutdown(cli);
754                         return ret;
755                 }
756                 ret = cli_RNetUserEnum(cli, user_fn, NULL); 
757                 cli_shutdown(cli);
758                 return ret;
759         }
760
761         return net_run_function(argc, argv, func, net_rap_user_usage);
762 }
763
764
765 int net_rap_group_usage(int argc, const char **argv)
766 {
767         d_printf("net rap group [misc. options] [targets]"\
768                  "\n\tList user groups\n");
769         d_printf("\nnet rap group DELETE <name> [misc. options] [targets]"\
770                  "\n\tDelete specified group\n");
771         d_printf("\nnet rap group ADD <name> [-C comment] [misc. options]"\
772                  " [targets]\n\tCreate specified group\n");
773
774         general_rap_usage(argc, argv);
775         d_printf(
776          "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
777         return -1;
778 }
779
780 static void long_group_fn(const char *group_name, const char *comment,
781                           void *state)
782 {
783         d_printf("%-21.21s %-50.50s\n", group_name, comment);
784 }
785
786 static void group_fn(const char *group_name, const char *comment, void *state)
787 {
788         d_printf("%-21.21s\n", group_name);
789 }
790
791 static int rap_group_delete(int argc, const char **argv)
792 {
793         struct cli_state *cli;
794         int ret;
795         if (argc == 0) {
796                 d_printf("\n\nGroup name not specified\n");
797                 return net_rap_group_usage(argc, argv);
798         }
799
800         if (!(cli = net_make_ipc_connection(0)))
801                 return -1;
802
803         ret = cli_NetGroupDelete(cli, argv[0]);
804         cli_shutdown(cli);
805         return ret;
806 }
807
808 static int rap_group_add(int argc, const char **argv)
809 {
810         struct cli_state *cli;
811         int ret;
812         RAP_GROUP_INFO_1 grinfo;
813
814         if (argc == 0) {
815                 d_printf("\n\nGroup name not specified\n");
816                 return net_rap_group_usage(argc, argv);
817         }
818
819         if (!(cli = net_make_ipc_connection(0)))
820                 return -1;
821                         
822         /* BB check for length 21 or smaller explicitly ? BB */
823         safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name));
824         grinfo.reserved1 = '\0';
825         grinfo.comment = opt_comment;
826         
827         ret = cli_NetGroupAdd(cli, &grinfo);
828         cli_shutdown(cli);
829         return ret;
830 }
831
832 int net_rap_group(int argc, const char **argv)
833 {
834         struct functable func[] = {
835                 {"ADD", rap_group_add},
836                 {"DELETE", rap_group_delete},
837                 {NULL, NULL}
838         };
839
840         if (argc == 0) {
841                 struct cli_state *cli;
842                 int ret;
843                 if (!(cli = net_make_ipc_connection(0)))
844                         return -1;
845                 if (opt_long_list_entries) {
846                         d_printf("Group name            Comment\n");
847                         d_printf("-----------------------------\n");
848                         ret = cli_RNetGroupEnum(cli, long_group_fn, NULL);
849                         cli_shutdown(cli);
850                         return ret;
851                 }
852                 ret = cli_RNetGroupEnum(cli, group_fn, NULL); 
853                 cli_shutdown(cli);
854                 return ret;
855         }
856
857         return net_run_function(argc, argv, func, net_rap_group_usage);
858 }
859
860 int net_rap_groupmember_usage(int argc, const char **argv)
861 {
862         d_printf(
863          "net rap groupmember LIST <group> [misc. options] [targets]"\
864          "\n\t Enumerate users in a group\n"\
865          "\nnet rap groupmember DELETE <group> <user> [misc. options] "\
866          "[targets]\n\t Delete sepcified user from specified group\n"\
867          "\nnet rap groupmember ADD <group> <user> [misc. options] [targets]"\
868          "\n\t Add specified user to specified group\n");
869
870         general_rap_usage(argc, argv);
871         return -1;
872 }
873
874
875 static int rap_groupmember_add(int argc, const char **argv)
876 {
877         struct cli_state *cli;
878         int ret;
879         if (argc != 2) {
880                 d_printf("\n\nGroup or user name not specified\n");
881                 return net_rap_groupmember_usage(argc, argv);
882         }
883
884         if (!(cli = net_make_ipc_connection(0)))
885                 return -1;
886
887         ret = cli_NetGroupAddUser(cli, argv[0], argv[1]);
888         cli_shutdown(cli);
889         return ret;
890 }
891
892 static int rap_groupmember_delete(int argc, const char **argv)
893 {
894         struct cli_state *cli;
895         int ret;
896         if (argc != 2) {
897                 d_printf("\n\nGroup or user name not specified\n");
898                 return net_rap_groupmember_usage(argc, argv);
899         }
900         
901         if (!(cli = net_make_ipc_connection(0)))
902                 return -1;
903
904         ret = cli_NetGroupDelUser(cli, argv[0], argv[1]);
905         cli_shutdown(cli);
906         return ret;
907 }
908
909 static int rap_groupmember_list(int argc, const char **argv)
910 {
911         struct cli_state *cli;
912         int ret;
913         if (argc == 0) {
914                 d_printf("\n\nGroup name not specified\n");
915                 return net_rap_groupmember_usage(argc, argv);
916         }
917
918         if (!(cli = net_make_ipc_connection(0)))
919                 return -1;
920
921         ret = cli_NetGroupGetUsers(cli, argv[0], group_member_fn, NULL ); 
922         cli_shutdown(cli);
923         return ret;
924 }
925
926 int net_rap_groupmember(int argc, const char **argv)
927 {
928         struct functable func[] = {
929                 {"ADD", rap_groupmember_add},
930                 {"LIST", rap_groupmember_list},
931                 {"DELETE", rap_groupmember_delete},
932                 {NULL, NULL}
933         };
934         
935         return net_run_function(argc, argv, func, net_rap_groupmember_usage);
936 }
937
938 int net_rap_validate_usage(int argc, const char **argv)
939 {
940         d_printf("net rap validate <username> [password]\n"\
941                  "\tValidate user and password to check whether they"\
942                  " can access target server or domain\n");
943
944         general_rap_usage(argc, argv);
945         return -1;
946 }
947
948 int net_rap_validate(int argc, const char **argv)
949 {
950         return errmsg_not_implemented();
951 }
952
953 int net_rap_service_usage(int argc, const char **argv)
954 {
955         d_printf("net rap service [misc. options] [targets] \n"\
956                  "\tlists all running service daemons on target server\n");
957         d_printf("\nnet rap service START <name> [service startup arguments]"\
958                  " [misc. options] [targets]"\
959                  "\n\tStart named service on remote server\n");
960         d_printf("\nnet rap service STOP <name> [misc. options] [targets]\n"\
961                  "\n\tStop named service on remote server\n");
962     
963         general_rap_usage(argc, argv);
964         return -1;
965 }
966
967 static int rap_service_start(int argc, const char **argv)
968 {
969         return errmsg_not_implemented();
970 }
971
972 static int rap_service_stop(int argc, const char **argv)
973 {
974         return errmsg_not_implemented();
975 }
976
977 int net_rap_service(int argc, const char **argv)
978 {
979         struct functable func[] = {
980                 {"START", rap_service_start},
981                 {"STOP", rap_service_stop},
982                 {NULL, NULL}
983         };
984
985         if (argc == 0) {
986                 struct cli_state *cli;
987                 int ret;
988                 if (!(cli = net_make_ipc_connection(0))) 
989                         return -1;
990
991                 if (opt_long_list_entries) {
992                         d_printf("Service name          Comment\n");
993                         d_printf("-----------------------------\n");
994                         ret = cli_RNetServiceEnum(cli, long_group_fn, NULL);
995                 }
996                 ret = cli_RNetServiceEnum(cli, group_fn, NULL); 
997                 cli_shutdown(cli);
998                 return ret;
999         }
1000
1001         return net_run_function(argc, argv, func, net_rap_service_usage);
1002 }
1003
1004 int net_rap_password_usage(int argc, const char **argv)
1005 {
1006         d_printf(
1007          "net rap password <user> <oldpwo> <newpw> [misc. options] [target]\n"\
1008          "\tchanges the password for the specified user at target\n"); 
1009         
1010         return -1;
1011 }
1012
1013
1014 int net_rap_password(int argc, const char **argv)
1015 {
1016         struct cli_state *cli;
1017         int ret;
1018         
1019         if (argc < 3) 
1020                 return net_rap_password_usage(argc, argv);
1021
1022         if (!(cli = net_make_ipc_connection(0))) 
1023                 return -1;
1024
1025         /* BB Add check for password lengths? */
1026         ret = cli_oem_change_password(cli, argv[0], argv[2], argv[1]);
1027         cli_shutdown(cli);
1028         return ret;
1029 }
1030
1031 int net_rap_admin_usage(int argc, const char **argv)
1032 {
1033         d_printf(
1034    "net rap admin <remote command> [cmd args [env]] [misc. options] [targets]"\
1035    "\n\texecutes a remote command on an os/2 target server\n"); 
1036         
1037         return -1;
1038 }
1039
1040
1041 int net_rap_admin(int argc, const char **argv)
1042 {
1043         return errmsg_not_implemented();
1044 }
1045
1046 /* The help subsystem for the RAP subcommand */
1047
1048 int net_rap_usage(int argc, const char **argv)
1049 {
1050         d_printf("  net rap domain \tto list domains \n"\
1051                  "  net rap file \tto list open files on a server \n"\
1052                  "  net rap group \tto list user groups  \n"\
1053                  "  net rap groupmember to list users in a group \n"\
1054                  "  net rap password\t to change the password of a user\n"\
1055                  "  net rap printq \tto list the print queues on a server\n"\
1056                  "  net rap server \tto list servers in a domain\n"\
1057                  "  net rap session \tto list clients with open sessions to a server\n"\
1058                  "  net rap share \tto list shares exported by a server\n"\
1059                  "  net rap user \tto list users\n"\
1060                  "  net rap validate \tto check whether a user and the corresponding password are valid\n"\
1061                  "  net rap help\n"\
1062                  "\nType \"net help <option>\" to get more information on that option\n\n");
1063
1064         general_rap_usage(argc, argv);
1065         return -1;
1066 }
1067
1068 int rap_help_usage(int argc, const char **argv)
1069 {
1070         d_printf("\n"\
1071                  "Usage: net rap help <function>\n"\
1072                  "\n"\
1073                  "Valid functions are:\n"\
1074                  "  FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP\n"\
1075                  "  VALIDATE GROUPMEMBER ADMIN SERVICE PASSWORD\n");
1076         return -1;
1077 }
1078
1079 /*
1080   handle "net help rap *" subcommands
1081 */
1082 static int net_rap_help(int argc, const char **argv)
1083 {
1084         struct functable func[] = {
1085                 {"FILE", net_rap_file_usage},
1086                 {"SHARE", net_rap_share_usage},
1087                 {"SESSION", net_rap_session_usage},
1088                 {"SERVER", net_rap_server_usage},
1089                 {"DOMAIN", net_rap_domain_usage},
1090                 {"PRINTQ", net_rap_printq_usage},
1091                 {"USER", net_rap_user_usage},
1092                 {"GROUP", net_rap_group_usage},
1093                 {"VALIDATE", net_rap_validate_usage},
1094                 {"GROUPMEMBER", net_rap_groupmember_usage},
1095                 {"ADMIN", net_rap_admin_usage},
1096                 {"SERVICE", net_rap_service_usage},
1097                 {"PASSWORD", net_rap_password_usage},
1098                 {NULL, NULL}};
1099
1100         return net_run_function(argc, argv, func, rap_help_usage);
1101 }
1102
1103 /* Entry-point for all the RAP functions. */
1104
1105 int net_rap(int argc, const char **argv)
1106 {
1107         struct functable func[] = {
1108                 {"FILE", net_rap_file},
1109                 {"SHARE", net_rap_share},
1110                 {"SESSION", net_rap_session},
1111                 {"SERVER", net_rap_server},
1112                 {"DOMAIN", net_rap_domain},
1113                 {"PRINTQ", net_rap_printq},
1114                 {"USER", net_rap_user},
1115                 {"GROUP", net_rap_group},
1116                 {"VALIDATE", net_rap_validate},
1117                 {"GROUPMEMBER", net_rap_groupmember},
1118                 {"ADMIN", net_rap_admin},
1119                 {"SERVICE", net_rap_service},   
1120                 {"PASSWORD", net_rap_password},
1121                 {"HELP", net_rap_help},
1122                 {NULL, NULL}
1123         };
1124         
1125         return net_run_function(argc, argv, func, net_rap_usage);
1126 }
1127