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