Adding support for net password, net service, net user info, fixing net helps
[Samba/wip.git] / source3 / utils / net.c
blobdcbc58017de63ab11ca61040ec76be422f670039
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)
8 connect_to_ipc based on similar routine
9 Copyright (C) Andrew Tridgell 1994-1998
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /*****************************************************/
27 /* */
28 /* Distributed SMB/CIFS Server Management Utility */
29 /* */
30 /* The intent was to make the syntax similar */
31 /* to the NET utility (first developed in DOS */
32 /* with additional interesting & useful functions */
33 /* added in later SMB server network operating */
34 /* systems). */
35 /* */
36 /*****************************************************/
38 #include <includes.h>
40 /***********************************************************************/
41 /* Beginning of internationalization section. Translatable constants */
42 /* should be kept in this area and referenced in the rest of the code. */
43 /* */
44 /* No functions, outside of Samba or LSB (Linux Standards Base) should */
45 /* be used (if possible). */
46 /***********************************************************************/
48 typedef struct _functable {
49 int func;
50 char funcname[12];
51 } functable;
53 /* functions available */
54 #define FILEF 1
55 #define SHAREF 2
56 #define SESSIONF 3
57 #define SERVERF 4
58 #define DOMAINF 5
59 #define PRINTQF 6
60 #define USERF 7
61 #define GROUPF 8
62 #define VALIDATEF 9
63 #define GROUPMEMBERF 10
64 #define ADMINF 11
65 #define SERVICEF 12
66 #define PASSWORDF 13
67 #define HELPF 14
69 const functable net_func[] = {
70 { FILEF, "FILE"},
71 { SHAREF, "SHARE"},
72 { SESSIONF, "SESSION"},
73 { SERVERF, "SERVER"},
74 { DOMAINF, "DOMAIN"},
75 { PRINTQF, "PRINTQ"},
76 { USERF, "USER"},
77 { GROUPF, "GROUP"},
78 { VALIDATEF, "VALIDATE"},
79 { GROUPMEMBERF, "GROUPMEMBER"},
80 { ADMINF, "ADMIN"},
81 { SERVICEF, "SERVICE"},
82 { PASSWORDF, "PASSWORD"},
83 { HELPF, "HELP"}
86 /* subfunctions available */
87 #define OTHER_SF 0
88 #define LIST_SF 1 /* enumerate */
89 #define ADD_SF 2 /* also used for create and start */
90 #define DELETE_SF 3 /* also used for close and stop */
91 #define INFO_SF 4 /* get information */
93 const functable net_subfunc[] = {
94 { LIST_SF, "LIST" },
95 { LIST_SF, "ENUMERATE" },
96 { ADD_SF, "ADD" },
97 { ADD_SF, "CREATE" },
98 { DELETE_SF, "CLOSE" },
99 { DELETE_SF, "DELETE" },
100 { INFO_SF, "INFO"}
103 const char share_type[][6] = {
104 "Disk",
105 "Print",
106 "Dev",
107 "IPC"
110 #define PASSWORD_PROMPT "Password: "
111 #define YES_STRING "Yes"
112 #define NO_STRING "No"
114 #define NET_USAGE \
115 "\nUsage: \n"\
116 " net domain \tto list domains \n"\
117 " net file \tto list open files on a server \n"\
118 " net group \tto list user groups \n"\
119 " net groupmember to list users in a group \n"\
120 " net password to change the password of a user\n"\
121 " net printq \tto list the print queues on a server\n"\
122 " net server \tto list servers in a domain\n"\
123 " net session \tto list clients with open sessions to a server\n"\
124 " net share \tto list shares exported by a server\n"\
125 " net user \tto list users\n"\
126 " net validate \tto check whether a user and the corresponding password are valid\n"\
127 " net help\n"\
128 "\nType \"net help <option>\" to get more information on that option\n"
130 #define NET_FILE_USAGE \
131 "\nnet file [misc. options] [targets]"\
132 "\n\tenumerates all open files on file server\n"\
133 "\nnet file <username> [misc. options] [targets]"\
134 "\n\tenumerates all files opened by username on file server\n"\
135 "\nnet file CLOSE <id> [misc. options] [targets]"\
136 "\n\tcloses specified file on target server\n"
138 #define FILE_INFO_DISPLAY \
139 "File ID %d\n"\
140 "User name %s\n"\
141 "Locks 0x%-4.2x\n"\
142 "Path %s\n"\
143 "Permissions 0x%x\n"
144 #define FILE_ENUM_DISPLAY \
145 "\nEnumerating open files on remote server:\n\n"\
146 "\n\tFileId Opened by Perms Locks Path \n"\
147 "\t------ --------- ----- ----- ---- \n"
149 #define NET_SHARE_USAGE \
150 "\nnet share [misc. options] [targets] \n"\
151 "\tenumerates all exported resources (network shares) on target server\n"\
152 "\nnet share ADD <name=serverpath> [misc. options] [targets]"\
153 "\n\tAdd a share from a server (makes the export active)\n"\
154 "\nnet share DELETE <sharename> [misc. options] [targets]\n"\
155 "\tor"\
156 "\nnet share CLOSE <sharename> [misc. options] [targets]"\
157 "\n\tDeletes a share from a server (makes the export inactive)\n"
159 #define SHARE_ENUM_DISPLAY \
160 "\nEnumerating shared resources (exports) on remote server:\n\n"\
161 "\nShare name Type Description\n"\
162 "---------- ---- -----------\n"
165 #define NET_SESSION_USAGE \
166 "\nnet session [misc. options] [targets]"\
167 "\n\tenumerates all active SMB/CIFS sessions on target server\n"\
168 "\nnet session DELETE <client_name> [misc. options] [targets] \n"\
169 "\tor"\
170 "\nnet session CLOSE <client_name> [misc. options] [targets]"\
171 "\n\tDeletes (closes) a session from specified client to server\n"
173 #define SESSION_ENUM_DISPLAY \
174 "Computer User name Client Type Opens Idle time\n\n"\
175 "------------------------------------------------------------------------------\n"
178 #define SESSION_DISPLAY_ONE \
179 "User name %-20.20s\n"\
180 "Computer %-20.20s\n"\
181 "Guest logon %-20.20s\n"\
182 "Client Type %-40.40s\n"\
183 "Sess time %2.2d:%2.2d:%2.2d\n"\
184 "Idle time %2.2d:%2.2d:%2.2d\n"
186 #define SESSION_DISPLAY_CONNS \
187 "Share name Type # Opens\n"\
188 "------------------------------------------------------------------------------\n"
190 #define NET_SERVER_USAGE \
191 "\nUsage:\n"\
192 " net server [domain]\tlists the servers in the specified domain or workgroup.\n"\
193 " If domain is not specified, it uses the current domain or workgroup as\n"\
194 " the default.\n"
196 #define SERVER_ENUM_DISPLAY "\nEnumerating servers in this domain or workgroup: \n\n" \
197 "\n\tServer name Server description\n"\
198 "\t------------- ----------------------------\n"
201 #define NET_DOMAIN_USAGE \
202 "\nUsage:\n"\
203 " net domain [misc. options] [target]\n\tlists the domains "\
204 "or workgroups visible on the current network\n"
206 #define DOMAIN_ENUM_DISPLAY \
207 "\nEnumerating domains:\n\n"\
208 "\n\tDomain name Server name of Browse Master\n"\
209 "\t------------- ----------------------------\n"
211 #define NET_PRINTQ_USAGE \
212 "\nUsage:\n"\
213 " net printq [misc. options] [targets]\n"\
214 "\tor\n"\
215 " net printq list [<queue_name>] [misc. options] [targets]\n"\
216 "\tlists the specified queue and jobs on the target server.\n"\
217 "\tIf the queue name is not specified, all queues are listed.\n\n"\
218 " net printq delete [<queue name>] [misc. options] [targets]\n"\
219 "\tdeletes the specified job number on the target server, or the\n"\
220 "\tprinter queue if no job number is specified\n"
221 #define PRINTQ_ENUM_DISPLAY \
222 "Print queues at \\\\%s\n\n"\
223 "Name Job # Size Status\n\n"\
224 "------------------------------------------------------------------"\
225 "-------------\n"
226 #define PRINTQ_DISPLAY_ONE "%-23.23s %5d jobs %-22.22s\n"
227 #define PRINTQ_PRINTER_ACTIVE "*Printer Active*"
228 #define PRINTQ_PRINTER_PAUSED "*Printer Paused*"
229 #define PRINTQ_PRINTER_ERROR "*Printer error*"
230 #define PRINTQ_PRINTER_DELPEND "*Delete Pending*"
231 #define PRINTQ_PRINTER_STATUNK "**UNKNOWN STATUS**"
232 #define PRINTQ_DISPLAY_JOB " %-23.23s %5d %9d %-22.22s\n"
233 #define PRINTQ_JOB_PRINTING "Printing"
234 #define PRINTQ_JOB_QUEUED "Waiting"
235 #define PRINTQ_JOB_PAUSED "Held in queue"
236 #define PRINTQ_JOB_SPOOLING "Spooling"
237 #define PRINTQ_QUEUE_WORD " Queue"
239 #define NET_USER_USAGE \
240 "\nnet user [misc. options] [targets]\n\tEnumerate users\n"\
241 "\nnet user DELETE <name> [misc. options] [targets]"\
242 "\n\tDelete specified user\n"\
243 "\nnet user INFO <name> [misc. options] [targets]"\
244 "\n\tList the domain groups of the specified user\n"\
245 "\nnet user ADD <name> [-F user flags] [misc. options] [targets]"\
246 "\n\tAdd specified user\n"
248 #define USER_ENUM_DISPLAY \
249 "\nEnumerating shared resources (exports) on remote server:\n\n"\
250 "\nUser name Description Home Directory Profile Directory\n"\
251 "--------- ----------- -------------- -----------------\n"
253 #define NET_GROUP_USAGE \
254 "\nnet group [misc. options] [targets]"\
255 "\n\tEnumerate user groups\n"\
256 "\nnet group DELETE <name> [misc. options] [targets]"\
257 "\n\tDelete specified group\n"\
258 "\nnet group ADD <name> [-C comment] [misc. options] [targets]"\
259 "\n\tCreate specified group\n"
261 #define NET_GROUPMEMBER_USAGE \
262 "\nnet groupmember LIST <group name> [misc. options] [targets]"\
263 "\n\t Enumerate users in a group\n"\
264 "\nnet groupmember DELETE <group name> <user name> [misc. options] "\
265 "[targets]\n\t Delete sepcified user from specified group\n"\
266 "\nnet groupmember ADD <group name> <user name> [misc. options] [targets]"\
267 "\n\t Add specified user to specified group\n"
270 #define NET_ADMIN_USAGE \
271 "\nnet admin <remote command to execute> [cmd arguments [environment]] [misc_options] [targets]\n"\
272 "\texecutes a remote command on an os/2 target server\n"
274 #define NET_PASSWORD_USAGE \
275 "\nnet password <user> <old password> <new password> [misc_options] [targets]\n"\
276 "\tchanges the password for the specified user on a remote server\n"
278 #define NET_SERVICE_USAGE \
279 "\nnet service [misc. options] [targets] \n"\
280 "\tenumerates all running service daemons on target server\n"\
281 "\nnet service ADD <name> [service startup arguments] [misc. options] [targets]"\
282 "\n\tStart named service on remote server\n"\
283 "\nnet service DELETE <name> [misc. options] [targets]\n"\
284 "\n\tStop named service on remote server\n"
287 #define NET_VALIDATE_USAGE \
288 "\nnet validate <username> [password]\n"\
289 "\tValidate user and password to check whether they can access target server or domain\n"
291 #define TARGET_USAGE "\nValid targets: choose one (none defaults to using the %s)\n"
292 #define GLBL_LCL_MASTER "global browsemaster or local browse master if that is not found"
293 #define DOMAIN_MASTER "local domain browse master"
294 #define LOCAL_HOST "localhost"
295 #define MISC_OPT_USAGE "\nValid miscellaneous options are:\n"
296 #define SERVER_USAGE "\t-S or --server=<server>\t\tserver name\n"
297 #define IPADDRESS_USAGE "\t-I or --ipaddress=<ipaddr>\tip address of target server\n"
298 #define PORT_USAGE "\t-p or --port=<port number>\tconnection port on target server\n"
299 #define WORKGROUP_USAGE "\t-w or --workgroup=<wg>\t\ttarget workgroup or domain name\n"
300 #define COMMENT_USAGE "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"
301 #define MYWORKGROUP_USAGE "\t-W or --myworkgroup=<wg>\tclient workgroup\n"
302 #define DEBUG_USAGE "\t-d or --debug=<level>\t\tdebug level (1-9)\n"
303 #define MYNAME_USAGE "\t-n or --myname=<name>\t\tclient name\n"
304 #define USER_USAGE "\t-U or --user=<name>\t\tuser name\n"
305 #define CONF_USAGE "\t-s or --conf=<path>\t\tpathname of smb.conf file\n"
306 #define JOBID_USAGE "\t-j or --jobid=<job id>\t\tjob id\n"
307 #define MAXUSERS_USAGE "\t-M or --maxusers=<num>\t\tmax users allowed for share\n"
308 #define LONG_USAGE "\t-l or --long\t\t\tDisplay full information\n"
310 #define ERRMSG_NOCONN_TARGET_SRVR "\nUnable to connect to target server\n"
311 #define ERRMSG_NOCONN_BROWSE_MSTR "\nUnable to connect to browse master\n"
312 #define ERRMSG_NOT_IMPLEMENTED "\nNot implemented\n"
313 #define ERRMSG_FILEID_MISSING "\nMissing fileid of file to close\n\n"
314 #define ERRMSG_GROUPNAME_MISSING "\n\nGroup name not specified\n"
315 #define ERRMSG_USERNAME_MISSING "\n\nUser name not specified\n"
316 #define ERRMSG_SHARENAME_MISSING "\n\nShare name not specified\n"
317 #define ERRMSG_TARGET_WG_NOT_VALID "\nTarget workgroup option not valid "\
318 "except on net server command, ignored"
319 #define ERRMSG_INVALID_HELP_OPTION "\nInvalid help option\n"
320 #define ERRMSG_INVALID_OPTION "\nInvalid option %c (%d)\n"
321 #define ERRMSG_INVALID_IPADDRESS "\nInvalid ip address specified\n"
322 #define ERRMSG_SPURIOUS_PARM "\nInvalid paramater ignored: %s\n"
323 #define ERRMSG_BOTH_SERVER_IPADDRESS "\nTarget server and IP address both "\
324 "specified. Do not set both at the same time. The target IP address was used\n"
325 #define ERRMSG_INVALID_DOMAIN_ACTION "\nInvalid action for NET DOMAIN command"\
326 " ignored. Only listing domains permitted.\n"
328 /* Column headers */
329 #define COMMENT_STR "Comment "
330 #define USER_STR "User name "
331 #define GROUP_STR "Group name "
332 #define SERVICE_STR "Service name"
333 #define HOMED_STR "Home directory "
334 #define LOGONS_STR "Logon script "
335 /************************************************************************************/
336 /* end of internationalization section */
337 /************************************************************************************/
339 extern int optind, opterr, optopt;
340 extern struct in_addr ipzero;
342 struct cli_state *cli;
343 static pstring global_requester_name;
344 static pstring host; /* target server */
345 static pstring password;
346 static pstring global_user_name;
347 static pstring global_workgroup;
348 static int port = SMB_PORT;
349 static int long_list_entries = 0;
350 static BOOL got_pass = False;
351 static BOOL have_ip = False;
352 struct in_addr dest_ip;
354 int get_func(const char *parm)
356 int i;
358 for (i=0;i<=sizeof(net_func);i++)
359 if (StrnCaseCmp(parm, net_func[i].funcname,10) == 0)
360 return net_func[i].func;
361 return 0;
364 int get_subfunc(const char *parm)
366 int i;
368 for (i=0;i<=sizeof(net_subfunc);i++)
369 if (StrnCaseCmp(parm, net_subfunc[i].funcname,10) == 0)
370 return net_subfunc[i].func;
371 return 0;
374 /****************************************************************************
376 ****************************************************************************/
377 struct cli_state *connect_to_ipc(char *server)
379 struct cli_state *c;
380 struct nmb_name called, calling;
381 struct in_addr ip;
382 char *server_n;
383 fstring servicename;
384 char *sharename;
387 /* make a copy so we don't modify the global string 'service' */
388 safe_strcpy(servicename, "IPC$", sizeof(servicename)-1);
389 sharename = servicename;
390 if (*sharename == '\\') {
391 server = sharename+2;
392 sharename = strchr(server,'\\');
393 if (!sharename) return NULL;
394 *sharename = 0;
395 sharename++;
398 if(server == NULL)
399 return NULL; /* if ip addr specified, ascii version of ip address is used as host name */
401 server_n = server;
403 ip = ipzero;
404 make_nmb_name(&calling, global_requester_name, 0x0);
405 make_nmb_name(&called , server, 0x20);
407 again:
408 if (have_ip)
409 ip = dest_ip;
410 else ip = ipzero;
412 DEBUG(3,("Connecting to host=%s\\share=%s\n\n",
413 server, "IPC$"));
415 /* have to open a new connection */
416 if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) == 0) ||
417 !cli_connect(c, server_n, &ip)) {
418 DEBUG(1,("Connection to %s failed\n", server_n));
419 return NULL;
422 c->protocol = PROTOCOL_NT1;
424 if (!cli_session_request(c, &calling, &called)) {
425 char *p;
426 DEBUG(1,("session request to %s failed (%s)\n",
427 called.name, cli_errstr(c)));
428 cli_shutdown(c);
429 SAFE_FREE(c);
430 if ((p=strchr(called.name, '.'))) {
431 *p = 0;
432 goto again;
434 if (strcmp(called.name, "*SMBSERVER")) {
435 make_nmb_name(&called , "*SMBSERVER", 0x20);
436 goto again;
438 return NULL;
441 DEBUG(4,(" session request ok\n"));
443 if (!cli_negprot(c)) {
444 DEBUG(1,("protocol negotiation failed\n"));
445 cli_shutdown(c);
446 SAFE_FREE(c);
447 return NULL;
450 if (!got_pass) {
451 char *pass = getpass(PASSWORD_PROMPT);
452 if (pass) {
453 pstrcpy(password, pass);
457 if (!cli_session_setup(c, global_user_name,
458 password, strlen(password),
459 password, strlen(password),
460 global_workgroup)) {
461 /* try again with a null username */
462 if (!cli_session_setup(c, "", "", 0, "", 0, global_workgroup)) {
463 DEBUG(1,("session setup failed: %s\n", cli_errstr(c)));
464 cli_shutdown(c);
465 SAFE_FREE(c);
466 return NULL;
468 DEBUG(3,("Anonymous login successful\n"));
471 DEBUG(4,(" session setup ok\n"));
472 if (!cli_send_tconX(c, sharename, "?????",
473 password, strlen(password)+1)) {
474 DEBUG(1,("tree connect failed: %s\n", cli_errstr(c)));
475 cli_shutdown(c);
476 SAFE_FREE(c);
477 return NULL;
480 DEBUG(4,(" tconx ok\n"));
482 return c;
486 void usage(void)
488 printf(NET_USAGE);
491 void file_usage(void)
493 printf(NET_FILE_USAGE); /* command syntax */
495 printf(TARGET_USAGE, LOCAL_HOST); /* target options */
496 printf(SERVER_USAGE);
497 printf(IPADDRESS_USAGE);
499 printf(MISC_OPT_USAGE); /* misc options */
500 printf(PORT_USAGE);
501 printf(MYWORKGROUP_USAGE);
502 printf(DEBUG_USAGE);
503 printf(MYNAME_USAGE);
504 printf(USER_USAGE);
505 printf(CONF_USAGE);
508 /***************************************************************************
509 list info on an open file
510 ***************************************************************************/
511 static void file_fn(const char * pPath, const char * pUser, uint16 perms, uint16 locks, uint32 id)
513 printf("\t%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
514 id, pUser, perms, locks, pPath);
517 static void one_file_fn(const char *pPath, const char *pUser, uint16 perms, uint16 locks, uint32 id)
519 printf(FILE_INFO_DISPLAY, id, pUser, locks, pPath, perms);
522 int net_file(int subfunct, char * id)
524 struct in_addr target_ip;
526 if((have_ip == 0) && (host[0] == 0)) {
527 if (!resolve_name("localhost", &target_ip, 0x20)) {
528 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
529 return -1;
530 } else {
531 have_ip = True;
532 dest_ip = target_ip;
535 if(host[0] == 0) strncpy(host, inet_ntoa(dest_ip),16);
536 cli = connect_to_ipc(host);
537 if(!cli) {
538 printf(ERRMSG_NOCONN_TARGET_SRVR);
539 return -2;
542 if(subfunct == DELETE_SF) { /* close open file on remote server */
543 if(id == NULL) {
544 printf(ERRMSG_FILEID_MISSING);
545 return -1;
546 } else
547 return cli_NetFileClose(cli, atoi(id));
548 } else if(subfunct == LIST_SF) {
549 printf(FILE_ENUM_DISPLAY); /* file list header */
550 return cli_NetFileEnum(cli, NULL, NULL, file_fn);
551 } else if ((subfunct == OTHER_SF) && id) {
552 return cli_NetFileGetInfo(cli, atoi(id), one_file_fn);
553 } else file_usage();
554 return -1;
557 void share_usage(void)
559 printf(NET_SHARE_USAGE); /* command syntax */
561 printf(TARGET_USAGE, LOCAL_HOST); /* target options */
562 printf(SERVER_USAGE);
563 printf(IPADDRESS_USAGE);
565 printf(MISC_OPT_USAGE); /* misc options */
566 printf(PORT_USAGE);
567 printf(COMMENT_USAGE);
568 printf(MAXUSERS_USAGE);
569 printf(MYWORKGROUP_USAGE);
570 printf(DEBUG_USAGE);
571 printf(MYNAME_USAGE);
572 printf(USER_USAGE);
573 printf(CONF_USAGE);
576 void long_share_fn(const char *share_name, uint32 type, const char *comment, void *state)
578 printf("%-12.12s %-8.8s %-50.50s\n", share_name, share_type[type], comment);
581 void share_fn(const char *share_name, uint32 type, const char *comment, void *state)
583 printf("%-12.12s\n", share_name);
586 int net_share(int subfunct, char * sharename, char * comment, int maxusers)
588 struct in_addr target_ip;
590 if((have_ip == 0) && (host[0] == 0)) {
591 if (!resolve_name("localhost", &target_ip, 0x20)) {
592 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
593 return -1;
595 } else {
596 have_ip = True;
597 dest_ip = target_ip;
600 if(host[0] == 0)
601 strncpy(host, inet_ntoa(dest_ip),16);
602 cli = connect_to_ipc(host);
603 if(!cli) {
604 printf(ERRMSG_NOCONN_TARGET_SRVR);
605 return -2;
607 if (subfunct == DELETE_SF) {
608 if (sharename == NULL) {
609 printf(ERRMSG_SHARENAME_MISSING);
610 return -1;
611 } else
612 return cli_NetShareDelete(cli, sharename);
613 } else if (subfunct == LIST_SF) {
614 if(long_list_entries) {
615 printf(SHARE_ENUM_DISPLAY);
616 return cli_RNetShareEnum(cli, long_share_fn, NULL);
617 } else {
618 return cli_RNetShareEnum(cli, share_fn, NULL);
620 } else if (subfunct == ADD_SF) {
621 if (sharename == NULL) {
622 printf(ERRMSG_SHARENAME_MISSING);
623 return -1;
624 } else {
625 RAP_SHARE_INFO_2 sinfo;
626 char *p;
628 p = strchr(sharename, '=');
629 strncpy(sinfo.share_name, sharename, PTR_DIFF(p,sharename));
630 sinfo.reserved1 = '\0';
631 sinfo.share_type = 0;
632 sinfo.comment = comment;
633 sinfo.perms = 0;
634 sinfo.maximum_users = maxusers;
635 sinfo.active_users = 0;
636 sinfo.path = p+1;
637 bzero(sinfo.password, sizeof(sinfo.password));
638 sinfo.reserved2 = '\0';
640 return cli_NetShareAdd(cli, &sinfo);
642 } else
643 printf(ERRMSG_NOT_IMPLEMENTED);
644 return -1;
648 void session_usage(void)
650 printf(NET_SESSION_USAGE); /* command syntax */
652 printf(TARGET_USAGE, LOCAL_HOST); /* Target options */
653 printf(SERVER_USAGE);
654 printf(IPADDRESS_USAGE);
656 printf(MISC_OPT_USAGE); /* Misc options */
657 printf(PORT_USAGE);
658 printf(MYWORKGROUP_USAGE);
659 printf(DEBUG_USAGE);
660 printf(MYNAME_USAGE);
661 printf(USER_USAGE);
662 printf(CONF_USAGE);
665 void list_sessions_func(char *wsname, char *username, uint16 conns,
666 uint16 opens, uint16 users, uint32 sess_time,
667 uint32 idle_time, uint32 user_flags, char *clitype)
669 int hrs = idle_time / 3600;
670 int min = (idle_time / 60) % 60;
671 int sec = idle_time % 60;
673 printf("\\\\%-18.18s %-20.20s %-18.18s %5d %2.2d:%2.2d:%2.2d\n",
674 wsname, username, clitype, opens, hrs, min, sec);
677 void display_session_func(char *wsname, char *username, uint16 conns,
678 uint16 opens, uint16 users, uint32 sess_time,
679 uint32 idle_time, uint32 user_flags, char *clitype)
681 int ihrs = idle_time / 3600;
682 int imin = (idle_time / 60) % 60;
683 int isec = idle_time % 60;
684 int shrs = sess_time / 3600;
685 int smin = (sess_time / 60) % 60;
686 int ssec = sess_time % 60;
687 printf(SESSION_DISPLAY_ONE, username, wsname,
688 (user_flags&0x0)?YES_STRING:NO_STRING, clitype,
689 shrs, smin, ssec, ihrs, imin, isec);
692 void display_conns_func(uint16 conn_id, uint16 conn_type, uint16 opens, uint16 users, uint32 conn_time, char *username, char *netname)
694 printf("%-14.14s %-8.8s %5d\n", netname, share_type[conn_type], opens);
697 int net_session(int subfunct, char * sessname)
699 struct in_addr target_ip;
700 int res;
702 if((have_ip == 0) && (host[0] == 0)) {
703 if (!resolve_name("localhost", &target_ip, 0x20)) {
704 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
705 return -1;
707 } else {
708 have_ip = True;
709 dest_ip = target_ip;
712 if(host[0] == 0)
713 strncpy(host, inet_ntoa(dest_ip),16);
714 cli = connect_to_ipc(host);
715 if(!cli) {
716 printf(ERRMSG_NOCONN_TARGET_SRVR);
717 return -2;
719 switch(subfunct){
720 case LIST_SF:
721 if (sessname) {
722 res = cli_NetSessionGetInfo(cli, sessname, display_session_func);
723 if (res >= 0) {
724 printf(SESSION_DISPLAY_CONNS);
725 return cli_NetConnectionEnum(cli, sessname, display_conns_func);
726 } else
727 return res;
728 } else {
729 printf(SESSION_ENUM_DISPLAY);
730 return cli_NetSessionEnum(cli, list_sessions_func);
732 case DELETE_SF:
733 return cli_NetSessionDel(cli, sessname);
734 default:
735 printf(ERRMSG_NOT_IMPLEMENTED);
736 session_usage();
738 return -1;
741 /****************************************************************************
742 list a server name
743 ****************************************************************************/
744 static void display_server_func(const char *name, uint32 m, const char *comment, void * reserved)
746 printf("\t%-16.16s %s\n", name, comment);
750 void server_usage(void)
752 printf(NET_SERVER_USAGE); /* command syntax */
754 printf(TARGET_USAGE, DOMAIN_MASTER); /* Target options */
755 printf(SERVER_USAGE);
756 printf(IPADDRESS_USAGE);
757 printf(WORKGROUP_USAGE);
759 printf(MISC_OPT_USAGE); /* Misc options */
760 printf(PORT_USAGE);
761 printf(MYWORKGROUP_USAGE);
762 printf(DEBUG_USAGE);
763 printf(MYNAME_USAGE);
764 printf(USER_USAGE);
765 printf(CONF_USAGE);
768 int net_server(char * temp_workgroup, int subfunct)
770 /* try to find master browser for our domain - if we fail try to find pdc */
771 char our_workgroup[16];
772 struct in_addr brow_ips;
774 if((have_ip == 0) && (host[0] == 0)) {
775 /* find target server based on workgroup or domain */
776 if((temp_workgroup == 0) || (temp_workgroup[0] == 0))
777 temp_workgroup = lp_workgroup(); /* by default enum our local workgroup or domain */
779 safe_strcpy(our_workgroup, temp_workgroup,15);
781 if (!resolve_name(our_workgroup, &brow_ips, 0x1D)) {
782 /* go looking for workgroups */
783 DEBUG(1,("Unable to resolve master browser via name lookup\n"));
784 return -2;
785 } else {
786 have_ip = True;
787 dest_ip = brow_ips;
790 if(host[0] == 0) strncpy(host, inet_ntoa(dest_ip),16);
791 cli = connect_to_ipc(host);
792 if(!cli) {
793 printf(ERRMSG_NOCONN_BROWSE_MSTR);
794 return -2;
796 printf(SERVER_ENUM_DISPLAY); /* header for list of servers */
797 return cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, display_server_func,NULL);
799 /* BB add mechanism to find PDC for our domain and send enum to it in this error case */
801 /* BB add server service (smb server daemon) start and stop */
804 void domain_usage(void)
806 printf(NET_DOMAIN_USAGE); /* command syntax */
808 printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
809 printf(SERVER_USAGE);
810 printf(IPADDRESS_USAGE);
812 printf(MISC_OPT_USAGE); /* misc options */
813 printf(PORT_USAGE);
814 printf(MYWORKGROUP_USAGE);
815 printf(DEBUG_USAGE);
816 printf(MYNAME_USAGE);
817 printf(USER_USAGE);
818 printf(CONF_USAGE);
822 int net_domain(void)
824 char *our_workgroup;
825 struct in_addr msbrow_ip;
828 our_workgroup = lp_workgroup();
829 if((have_ip == 0) && (host[0] == 0)) {
830 if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) {
831 DEBUG(1,("Unable to resolve global master browser via name lookup"));
832 if (!resolve_name(our_workgroup, &msbrow_ip, 0x1D)) {
833 DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
834 return -2;
835 } else {
836 have_ip = True;
837 dest_ip = msbrow_ip;
839 } else {
840 have_ip = True;
841 dest_ip = msbrow_ip;
844 if(host[0] == 0)
845 strncpy(host, inet_ntoa(dest_ip),16);
846 cli = connect_to_ipc(host);
847 if(!cli) {
848 printf(ERRMSG_NOCONN_BROWSE_MSTR);
849 return -2;
851 printf(DOMAIN_ENUM_DISPLAY); /* header for list of domains */
852 return cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, display_server_func,NULL);
856 void printq_usage(void)
858 printf(NET_PRINTQ_USAGE);
860 printf(TARGET_USAGE, LOCAL_HOST);
861 printf(SERVER_USAGE);
862 printf(IPADDRESS_USAGE);
864 printf(MISC_OPT_USAGE);
865 printf(PORT_USAGE);
866 printf(JOBID_USAGE);
867 printf(MYWORKGROUP_USAGE);
868 printf(DEBUG_USAGE);
869 printf(MYNAME_USAGE);
870 printf(USER_USAGE);
871 printf(CONF_USAGE);
874 void enum_queue(char *queuename, uint16 pri, uint16 start, uint16 until, char *sep, char *pproc, char *dest, char *qparms, char *qcomment, uint16 status, uint16 jobcount) {
875 pstring queuecol;
876 pstring statcol;
878 pstrcpy(queuecol, queuename);
879 pstrcat(queuecol, PRINTQ_QUEUE_WORD);
881 switch (status) {
882 case 0:
883 pstrcpy(statcol, PRINTQ_PRINTER_ACTIVE);
884 break;
885 case 1:
886 pstrcpy(statcol, PRINTQ_PRINTER_PAUSED);
887 break;
888 case 2:
889 pstrcpy(statcol, PRINTQ_PRINTER_ERROR);
890 break;
891 case 3:
892 pstrcpy(statcol, PRINTQ_PRINTER_DELPEND);
893 break;
894 default:
895 pstrcpy(statcol, PRINTQ_PRINTER_STATUNK);
897 printf(PRINTQ_DISPLAY_ONE, queuecol, jobcount, statcol);
900 void enum_jobs(uint16 jobid, char *ownername, char *notifyname, char *datatype, char *jparms, uint16 pos, uint16 status, char *jstatus, uint submitted, uint jobsize, char *comment) {
901 pstring statcol;
903 switch (status) {
904 case 0:
905 pstrcpy(statcol, PRINTQ_JOB_QUEUED);
906 break;
907 case 1:
908 pstrcpy(statcol, PRINTQ_JOB_PAUSED);
909 break;
910 case 2:
911 pstrcpy(statcol, PRINTQ_JOB_SPOOLING);
912 break;
913 case 3:
914 pstrcpy(statcol, PRINTQ_JOB_PRINTING);
915 break;
916 default:
917 pstrcpy(statcol, PRINTQ_PRINTER_STATUNK);
919 printf(PRINTQ_DISPLAY_JOB, ownername, jobid, jobsize, statcol);
922 int net_printq(int subfunct, char * printq, int jobid)
924 struct in_addr target_ip;
926 if((have_ip == 0) && (host[0] == 0)) {
927 if (!resolve_name("localhost", &target_ip, 0x20)) {
928 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
929 return -1;
931 } else {
932 have_ip = True;
933 dest_ip = target_ip;
936 if(host[0] == 0)
937 strncpy(host, inet_ntoa(dest_ip),16);
938 cli = connect_to_ipc(host);
939 if(!cli) {
940 printf(ERRMSG_NOCONN_TARGET_SRVR);
941 return -2;
943 switch(subfunct) {
944 case LIST_SF:
945 printf(PRINTQ_ENUM_DISPLAY, host);
946 if (printq)
947 return cli_NetPrintQGetInfo(cli, printq, enum_queue, enum_jobs);
948 else
949 return cli_NetPrintQEnum(cli, enum_queue, enum_jobs);
950 case DELETE_SF:
951 return cli_printjob_del(cli, jobid);
952 default:
953 printf(ERRMSG_NOT_IMPLEMENTED);
954 return -1;
960 void user_usage(void)
962 printf(NET_USER_USAGE); /* command syntax */
964 printf(TARGET_USAGE, LOCAL_HOST); /* target options */
965 printf(SERVER_USAGE);
966 printf(IPADDRESS_USAGE);
967 printf(WORKGROUP_USAGE);
969 printf(MISC_OPT_USAGE); /* misc options */
970 printf(PORT_USAGE);
971 printf(COMMENT_USAGE);
972 printf(MYWORKGROUP_USAGE);
973 printf(DEBUG_USAGE);
974 printf(MYNAME_USAGE);
975 printf(USER_USAGE);
976 printf(CONF_USAGE);
977 printf(LONG_USAGE);
980 void user_fn(const char *user_name, const char *comment, const char * home_dir, const char * logon_script, void *state)
982 printf("%-21.21s\n", user_name);
985 void long_user_fn(const char *user_name, const char *comment, const char * home_dir, const char * logon_script, void *state)
987 printf("%-21.21s %-47.47s %-35.35s %35.35s\n", user_name, comment, home_dir, logon_script);
990 void group_member_fn(const char *user_name, void *state)
992 printf("%-21.21s\n", user_name);
995 int net_user(int subfunct, char * username, char * comment, int flags)
997 struct in_addr target_ip;
999 if((have_ip == 0) && (host[0] == 0)) {
1000 if (!resolve_name("localhost", &target_ip, 0x20)) {
1001 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
1002 return -1;
1004 } else {
1005 have_ip = True;
1006 dest_ip = target_ip;
1009 if(host[0] == 0)
1010 strncpy(host, inet_ntoa(dest_ip),16);
1011 cli = connect_to_ipc(host);
1012 if(!cli) {
1013 printf(ERRMSG_NOCONN_TARGET_SRVR);
1014 return -2;
1016 if (subfunct == DELETE_SF) {
1017 if (username == NULL) {
1018 printf(ERRMSG_USERNAME_MISSING);
1019 return -1;
1020 } else
1021 return cli_NetUserDelete(cli, username);
1022 } else if (subfunct == LIST_SF) {
1023 if(long_list_entries) {
1024 printf(USER_ENUM_DISPLAY);
1025 return cli_RNetUserEnum(cli, long_user_fn, NULL);
1027 else
1028 return cli_RNetUserEnum(cli, user_fn, NULL);
1029 } else if (subfunct == ADD_SF) {
1030 if (username == NULL) {
1031 printf(ERRMSG_USERNAME_MISSING);
1032 return -1;
1033 } else {
1034 RAP_USER_INFO_1 userinfo;
1036 safe_strcpy(userinfo.user_name, username, sizeof(userinfo.user_name));
1037 if(flags == -1) flags = 0x21;
1039 userinfo.userflags = flags;
1040 userinfo.reserved1 = '\0';
1041 userinfo.comment = comment;
1042 userinfo.priv = 1;
1043 userinfo.home_dir = NULL;
1044 userinfo.logon_script = NULL;
1046 return cli_NetUserAdd(cli, &userinfo);
1048 } else if (subfunct == INFO_SF) {
1049 if (username == NULL) {
1050 printf(ERRMSG_USERNAME_MISSING);
1051 return -1;
1052 } else {
1053 /* RAP_USER_INFO_1 userinfo;
1054 cli_NetUserInfo (cli, &userinfo); */ /* BB need to add call to get user info level 3 or 4 */
1055 return cli_NetUserGetGroups(cli, username, group_member_fn, NULL );
1058 else
1059 printf(ERRMSG_NOT_IMPLEMENTED);
1060 return -1;
1065 void group_usage(void)
1067 printf(NET_GROUP_USAGE); /* command syntax */
1069 printf(TARGET_USAGE, LOCAL_HOST); /* target options */
1070 printf(SERVER_USAGE);
1071 printf(IPADDRESS_USAGE);
1073 printf(MISC_OPT_USAGE); /* misc options */
1074 printf(PORT_USAGE);
1075 printf(COMMENT_USAGE);
1076 printf(MYWORKGROUP_USAGE);
1077 printf(DEBUG_USAGE);
1078 printf(MYNAME_USAGE);
1079 printf(USER_USAGE);
1080 printf(WORKGROUP_USAGE);
1081 printf(CONF_USAGE);
1082 printf(LONG_USAGE);
1085 void long_group_fn(const char *group_name, const char *comment, void *state)
1087 printf("%-21.21s %-50.50s\n", group_name, comment);
1090 void group_fn(const char *group_name, const char *comment, void *state)
1092 printf("%-21.21s\n", group_name);
1095 int net_group(int subfunct, char * groupname, char * comment)
1097 struct in_addr target_ip;
1099 if((have_ip == 0) && (host[0] == 0)) {
1100 if (!resolve_name("localhost", &target_ip, 0x20)) {
1101 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
1102 return -1;
1104 } else {
1105 have_ip = True;
1106 dest_ip = target_ip;
1109 if(host[0] == 0)
1110 strncpy(host, inet_ntoa(dest_ip),16);
1111 cli = connect_to_ipc(host);
1112 if(!cli) {
1113 printf(ERRMSG_NOCONN_TARGET_SRVR);
1114 return -2;
1116 if (subfunct == DELETE_SF) {
1117 if (groupname == NULL) {
1118 printf(ERRMSG_GROUPNAME_MISSING);
1119 return -1;
1120 } else
1121 return cli_NetGroupDelete(cli, groupname);
1122 } else if (subfunct == LIST_SF) {
1123 if(long_list_entries) {
1124 printf("%-21.21s %-50.50s\n", GROUP_STR, COMMENT_STR);
1125 printf("-----------------------------\n");
1126 return cli_RNetGroupEnum(cli, long_group_fn, NULL);
1128 else
1129 return cli_RNetGroupEnum(cli, group_fn, NULL);
1130 } else if (subfunct == ADD_SF) {
1131 if (groupname == NULL) {
1132 printf(ERRMSG_GROUPNAME_MISSING);
1133 return -1;
1134 } else {
1135 RAP_GROUP_INFO_1 grinfo;
1137 /* BB check for length 21 or smaller explicitly ? BB */
1138 safe_strcpy(grinfo.group_name, groupname, sizeof(grinfo.group_name));
1139 grinfo.reserved1 = '\0';
1140 grinfo.comment = comment;
1142 return cli_NetGroupAdd(cli, &grinfo);
1144 } else
1145 printf(ERRMSG_NOT_IMPLEMENTED);
1146 return -1;
1149 void groupmember_usage(void)
1151 printf(NET_GROUPMEMBER_USAGE); /* command syntax */
1153 printf(TARGET_USAGE, LOCAL_HOST); /* target options */
1154 printf(SERVER_USAGE);
1155 printf(IPADDRESS_USAGE);
1157 printf(MISC_OPT_USAGE); /* misc options */
1158 printf(PORT_USAGE);
1159 printf(MYWORKGROUP_USAGE);
1160 printf(DEBUG_USAGE);
1161 printf(MYNAME_USAGE);
1162 printf(USER_USAGE);
1163 printf(WORKGROUP_USAGE);
1164 printf(CONF_USAGE);
1168 int net_groupmember(int subfunct, char * groupname, char * username)
1170 struct in_addr target_ip;
1172 if((have_ip == 0) && (host[0] == 0)) {
1173 if (!resolve_name("localhost", &target_ip, 0x20)) {
1174 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
1175 return -1;
1176 } else {
1177 have_ip = True;
1178 dest_ip = target_ip;
1181 if(host[0] == 0)
1182 strncpy(host, inet_ntoa(dest_ip),16);
1183 cli = connect_to_ipc(host);
1184 if(!cli) {
1185 printf(ERRMSG_NOCONN_TARGET_SRVR);
1186 return -2;
1188 if (groupname == NULL) {
1189 printf(ERRMSG_GROUPNAME_MISSING);
1190 return -1;
1193 if (subfunct == LIST_SF)
1194 return cli_NetGroupGetUsers(cli, groupname, group_member_fn, NULL );
1196 if (username == NULL) {
1197 printf(ERRMSG_USERNAME_MISSING);
1198 return -1;
1201 if (subfunct == DELETE_SF)
1202 return cli_NetGroupDelUser(cli, groupname, username);
1203 else if (subfunct == ADD_SF)
1204 return cli_NetGroupAddUser(cli, groupname, username);
1205 else
1206 printf(ERRMSG_NOT_IMPLEMENTED);
1207 return -1;
1211 void validate_usage(void)
1213 printf(NET_VALIDATE_USAGE); /* command syntax */
1215 printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
1216 printf(SERVER_USAGE);
1217 printf(IPADDRESS_USAGE);
1218 printf(WORKGROUP_USAGE);
1220 printf(MISC_OPT_USAGE); /* misc options */
1221 printf(PORT_USAGE);
1222 printf(MYWORKGROUP_USAGE);
1223 printf(DEBUG_USAGE);
1224 printf(MYNAME_USAGE);
1225 printf(USER_USAGE);
1226 printf(CONF_USAGE);
1229 int net_validate(char * username)
1231 printf(ERRMSG_NOT_IMPLEMENTED);
1232 return 0;
1235 void service_usage(void)
1237 printf(NET_SERVICE_USAGE); /* command syntax */
1239 printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
1240 printf(SERVER_USAGE);
1241 printf(IPADDRESS_USAGE);
1243 printf(MISC_OPT_USAGE); /* misc options */
1244 printf(PORT_USAGE);
1245 printf(MYWORKGROUP_USAGE);
1246 printf(DEBUG_USAGE);
1247 printf(MYNAME_USAGE);
1248 printf(USER_USAGE);
1249 printf(CONF_USAGE);
1253 int net_service(int subfunct, char * servicename, char * srvc_args)
1255 struct in_addr target_ip;
1257 if((have_ip == 0) && (host[0] == 0)) {
1258 if (!resolve_name("localhost", &target_ip, 0x20)) {
1259 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
1260 return -1;
1261 } else {
1262 have_ip = True;
1263 dest_ip = target_ip;
1266 if(host[0] == 0)
1267 strncpy(host, inet_ntoa(dest_ip),16);
1268 cli = connect_to_ipc(host);
1269 if(!cli) {
1270 printf(ERRMSG_NOCONN_TARGET_SRVR);
1271 return -2;
1274 if (subfunct == LIST_SF) {
1275 if(long_list_entries) {
1276 printf("%-15.15s %-50.50s\n", SERVICE_STR, COMMENT_STR);
1277 printf("-----------------------------\n");
1278 return cli_RNetServiceEnum(cli, long_group_fn, NULL);
1280 else
1281 return cli_RNetServiceEnum(cli, group_fn, NULL);
1282 } else
1283 printf(ERRMSG_NOT_IMPLEMENTED);
1284 return -1;
1288 int net_password(char * username, char * old_password, char * new_password)
1290 struct in_addr target_ip;
1292 if((have_ip == 0) && (host[0] == 0)) {
1293 if (!resolve_name("localhost", &target_ip, 0x20)) {
1294 DEBUG(1,("No remote server specified, unable to resolve connection to localhost via name lookup"));
1295 return -1;
1297 } else {
1298 have_ip = True;
1299 dest_ip = target_ip;
1302 if(host[0] == 0)
1303 strncpy(host, inet_ntoa(dest_ip),16);
1304 cli = connect_to_ipc(host);
1305 if(!cli) {
1306 printf(ERRMSG_NOCONN_TARGET_SRVR);
1307 return -2;
1310 /* BB Add check for password lengths? */
1311 return cli_oem_change_password(cli, username, new_password, old_password);
1314 void password_usage(void)
1316 printf(NET_PASSWORD_USAGE); /* command syntax */
1318 printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
1319 printf(SERVER_USAGE);
1320 printf(IPADDRESS_USAGE);
1321 printf(WORKGROUP_USAGE);
1323 printf(MISC_OPT_USAGE); /* misc options */
1324 printf(PORT_USAGE);
1325 printf(MYWORKGROUP_USAGE);
1326 printf(DEBUG_USAGE);
1327 printf(MYNAME_USAGE);
1328 printf(USER_USAGE);
1329 printf(CONF_USAGE);
1333 void admin_usage(void)
1335 printf(NET_ADMIN_USAGE); /* command syntax */
1337 printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
1338 printf(SERVER_USAGE);
1339 printf(IPADDRESS_USAGE);
1340 printf(WORKGROUP_USAGE);
1342 printf(MISC_OPT_USAGE); /* misc options */
1343 printf(PORT_USAGE);
1344 printf(MYWORKGROUP_USAGE);
1345 printf(DEBUG_USAGE);
1346 printf(MYNAME_USAGE);
1347 printf(USER_USAGE);
1348 printf(CONF_USAGE);
1352 int net_admin(char * command, char * cmd_args, char * environment)
1354 printf(ERRMSG_NOT_IMPLEMENTED);
1355 return 0;
1359 /****************************************************************************
1360 main program
1361 ****************************************************************************/
1362 int main(int argc,char *argv[])
1364 int opt,i;
1365 char *p;
1366 int rc = 0;
1367 int func = 0;
1368 int subfunc = LIST_SF;
1369 int argc_new = 0;
1370 char ** argv_new;
1371 poptContext pc;
1372 static char *servicesf = CONFIGFILE;
1373 static char *target_workgroup = NULL;
1374 static char *comment = "";
1375 static char *user_name = NULL;
1376 static char *my_workgroup = NULL;
1377 static char *requester_name = NULL;
1378 static char *dest_host = NULL;
1379 static int maxusers = -1;
1380 static int flagsarg = -1;
1381 static int jobid = 0;
1382 static int debuglevel;
1384 static struct poptOption long_options[] = {
1385 {"help", 'h', POPT_ARG_NONE, 0, 'h'},
1386 {"workgroup", 'w', POPT_ARG_STRING, &target_workgroup},
1387 {"myworkgroup", 'W', POPT_ARG_STRING, &my_workgroup},
1388 {"user", 'U', POPT_ARG_STRING, &user_name, 'U'},
1389 {"ipaddress", 'I', POPT_ARG_STRING, 0, 'I'},
1390 {"port", 'p', POPT_ARG_INT, &port},
1391 {"myname", 'n', POPT_ARG_STRING, &requester_name},
1392 {"conf", 's', POPT_ARG_STRING, &servicesf},
1393 {"debug", 'd', POPT_ARG_INT, &debuglevel, 'd'},
1394 {"server", 'S', POPT_ARG_STRING, &dest_host},
1395 {"comment", 'C', POPT_ARG_STRING, &comment},
1396 {"maxusers", 'M', POPT_ARG_INT, &maxusers},
1397 {"flags", 'F', POPT_ARG_INT, &flagsarg},
1398 {"jobid", 'j', POPT_ARG_INT, &jobid},
1399 {"long", 'l', POPT_ARG_NONE, &long_list_entries},
1400 { 0, 0, 0, 0}
1403 got_pass = 0;
1404 dest_ip = ipzero;
1405 host[0] = 0;
1407 dbf = x_stdout;
1409 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
1410 POPT_CONTEXT_KEEP_FIRST);
1412 while((opt = poptGetNextOpt(pc)) != -1) {
1413 switch (opt) {
1414 case 'h':
1415 usage();
1416 exit(0);
1417 break;
1418 case 'd':
1419 DEBUGLEVEL=debuglevel;
1420 break;
1421 case 'I':
1422 dest_ip = *interpret_addr2(poptGetOptArg(pc));
1423 if(zero_ip(dest_ip))
1424 printf(ERRMSG_INVALID_IPADDRESS);
1425 else
1426 have_ip = True;
1427 break;
1428 case 'U':
1429 p = strchr(user_name,'%');
1430 pstrcpy(global_user_name, user_name);
1431 if (p) {
1432 *p = 0;
1433 pstrcpy(password,p+1);
1434 got_pass = 1;
1436 break;
1437 default:
1438 printf(ERRMSG_INVALID_OPTION, (char)opt, opt);
1439 usage();
1443 lp_load(servicesf,True,False,False);
1445 argv_new = (char **)poptGetArgs(pc);
1447 argc_new = argc;
1448 for (i=0; i<argc; i++) {
1449 if (argv_new[i] == NULL) {
1450 argc_new = i;
1451 break;
1455 if (argc_new < 2) {
1456 usage();
1457 return -1;
1460 func = get_func(argv_new[1]);
1462 if (func == 0)
1463 return -1;
1465 if (argc_new < 3) {
1466 if (func == VALIDATEF) {
1467 validate_usage();
1468 return -1;
1470 if (func == HELPF) {
1471 usage();
1472 return 0;
1476 if (func == HELPF) {
1477 switch(get_func(argv_new[2])) {
1478 case FILEF:
1479 file_usage();
1480 break;
1481 case SHAREF:
1482 share_usage();
1483 break;
1484 case SESSIONF:
1485 session_usage();
1486 break;
1487 case SERVERF:
1488 server_usage();
1489 break;
1490 case DOMAINF:
1491 domain_usage();
1492 break;
1493 case PRINTQF:
1494 printq_usage();
1495 break;
1496 case USERF:
1497 user_usage();
1498 break;
1499 case GROUPF:
1500 group_usage();
1501 break;
1502 case VALIDATEF:
1503 validate_usage();
1504 break;
1505 case SERVICEF:
1506 service_usage();
1507 break;
1508 case ADMINF:
1509 admin_usage();
1510 break;
1511 case GROUPMEMBERF:
1512 groupmember_usage();
1513 break;
1514 case PASSWORDF:
1515 password_usage();
1516 break;
1517 case HELPF:
1518 usage();
1519 break;
1520 default:
1521 printf(ERRMSG_INVALID_HELP_OPTION);
1522 usage();
1524 return 0;
1527 if (argc_new > 2) {
1528 /* parse next parm (argument 2) - i.e. sub function */
1529 subfunc = get_subfunc(argv_new[2]);
1531 if (func == 0) return -1;
1533 if (requester_name)
1534 pstrcpy(global_requester_name, requester_name);
1535 else
1536 get_myname(global_requester_name);
1538 if (user_name)
1539 pstrcpy(global_user_name, user_name);
1540 else if (getenv("LOGNAME"))
1541 pstrcpy(global_user_name,getenv("LOGNAME"));
1543 fstrcpy(global_workgroup, my_workgroup ? my_workgroup :lp_workgroup());
1545 if (dest_host)
1546 pstrcpy(host, dest_host);
1548 if((have_ip) && (host[0]))
1549 printf(ERRMSG_BOTH_SERVER_IPADDRESS);
1551 while (!got_pass) { /* BB if nulluser operation. why bother to ask for pword BB */
1552 p = getpass(PASSWORD_PROMPT);
1553 if (p) {
1554 pstrcpy(password, p);
1555 got_pass = 1;
1559 load_interfaces();
1561 switch (func) {
1562 case FILEF:
1563 if(argc_new <= 3) {
1564 if (subfunc == OTHER_SF)
1565 rc = net_file(subfunc, argv_new[2]);
1566 else
1567 rc = net_file(subfunc,NULL);
1568 } else
1569 rc = net_file(subfunc,argv_new[3]);
1570 break;
1571 case SHAREF:
1572 if (argc_new == 2)
1573 rc = net_share(subfunc, NULL, NULL, 0);
1574 else
1575 rc = net_share(subfunc,argv_new[3], comment, maxusers);
1576 break;
1577 case SESSIONF:
1578 if (argc_new <= 3)
1579 rc = net_session(subfunc,NULL);
1580 else
1581 rc = net_session(subfunc,argv_new[3]);
1582 break;
1583 case SERVERF:
1584 rc = net_server(target_workgroup, subfunc);
1585 break;
1586 case DOMAINF:
1587 if(subfunc != LIST_SF)
1588 printf(ERRMSG_INVALID_DOMAIN_ACTION);
1589 rc = net_domain();
1590 break;
1591 case USERF:
1592 if (argc_new == 2)
1593 rc = net_user(subfunc, NULL, NULL, -1);
1594 else if(argc_new == 3)
1595 rc = net_user(subfunc,NULL, NULL, -1);
1596 else if(argc_new > 3)
1597 rc = net_user(subfunc,argv_new[3], comment, flagsarg);
1598 break;
1599 case GROUPF:
1600 if (argc_new == 2)
1601 rc = net_group(subfunc, NULL, NULL);
1602 else if(argc_new == 3)
1603 rc = net_group(subfunc,NULL, NULL);
1604 else if(argc_new > 3)
1605 rc = net_group(subfunc,argv_new[3], comment);
1606 break;
1607 case GROUPMEMBERF:
1608 if (argc_new == 4)
1609 rc = net_groupmember(subfunc, argv_new[3], NULL);
1610 else if (argc_new == 5)
1611 rc = net_groupmember(subfunc, argv_new[3], argv_new[4]);
1612 else {
1613 groupmember_usage();
1614 rc = -1;
1616 break;
1617 case VALIDATEF:
1618 rc = net_validate(global_user_name);
1619 break;
1620 case SERVICEF:
1621 rc = net_service(subfunc, argv_new[3], argv_new[4]);
1622 break;
1623 case ADMINF:
1624 if(argc_new < 3)
1626 admin_usage();
1627 rc = -1;
1629 else if (argc_new == 3) {
1630 rc = net_admin(argv_new[2], NULL, NULL);
1631 } else if (argc_new == 4) {
1632 rc = net_admin(argv_new[2], argv_new[3], NULL);
1633 } else {
1634 rc = net_admin(argv_new[2], argv_new[3], argv_new[4]);
1636 break;
1637 case PASSWORDF:
1638 if(argc_new != 5)
1640 password_usage();
1641 rc = -1;
1642 } else {
1643 rc = net_password(argv_new[2], argv_new[3], argv_new[4]);
1645 break;
1646 case PRINTQF:
1647 if (argc_new <= 3)
1648 rc = net_printq(subfunc, NULL, jobid);
1649 else
1650 rc = net_printq(subfunc, argv_new[3], jobid);
1651 break;
1652 default:
1653 usage();
1654 return -1;
1656 DEBUG(1,("return code = %d\n", rc));
1657 return rc;