2 Samba Unix/Linux SMB client library
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)
9 Originally written by Steve and Jim. Largely rewritten by tridge in
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 /*****************************************************/
28 /* Distributed SMB/CIFS Server Management Utility */
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 */
36 /*****************************************************/
40 /***********************************************************************/
41 /* Beginning of internationalization section. Translatable constants */
42 /* should be kept in this area and referenced in the rest of the code. */
44 /* No functions, outside of Samba or LSB (Linux Standards Base) should */
45 /* be used (if possible). */
46 /***********************************************************************/
48 #define PASSWORD_PROMPT "Password: "
49 #define YES_STRING "Yes"
50 #define NO_STRING "No"
54 " net domain \tto list domains \n"\
55 " net file \tto list open files on a server \n"\
56 " net group \tto list user groups \n"\
57 " net groupmember to list users in a group \n"\
58 " net password\t to change the password of a user\n"\
59 " net printq \tto list the print queues on a server\n"\
60 " net server \tto list servers in a domain\n"\
61 " net session \tto list clients with open sessions to a server\n"\
62 " net share \tto list shares exported by a server\n"\
63 " net user \tto list users\n"\
64 " net validate \tto check whether a user and the corresponding password are valid\n"\
66 "\nType \"net help <option>\" to get more information on that option\n"
68 #define NET_FILE_USAGE \
69 "\nnet file [misc. options] [targets]"\
70 "\n\tenumerates all open files on file server\n"\
71 "\nnet file USER <username> [misc. options] [targets]"\
72 "\n\tenumerates all files opened by username on file server\n"\
73 "\nnet file CLOSE <id> [misc. options] [targets]"\
74 "\n\tcloses specified file on target server\n"
76 #define FILE_INFO_DISPLAY \
82 #define FILE_ENUM_DISPLAY \
83 "\nEnumerating open files on remote server:\n\n"\
84 "\n\tFileId Opened by Perms Locks Path \n"\
85 "\t------ --------- ----- ----- ---- \n"
87 #define NET_SHARE_USAGE \
88 "\nnet share [misc. options] [targets] \n"\
89 "\tenumerates all exported resources (network shares) on target server\n"\
90 "\nnet share ADD <name=serverpath> [misc. options] [targets]"\
91 "\n\tAdd a share from a server (makes the export active)\n"\
92 "\nnet share DELETE <sharename> [misc. options] [targets]\n"\
94 "\nnet share CLOSE <sharename> [misc. options] [targets]"\
95 "\n\tDeletes a share from a server (makes the export inactive)\n"
97 #define SHARE_ENUM_DISPLAY \
98 "\nEnumerating shared resources (exports) on remote server:\n\n"\
99 "\nShare name Type Description\n"\
100 "---------- ---- -----------\n"
103 #define NET_SESSION_USAGE \
104 "\nnet session [misc. options] [targets]"\
105 "\n\tenumerates all active SMB/CIFS sessions on target server\n"\
106 "\nnet session DELETE <client_name> [misc. options] [targets] \n"\
108 "\nnet session CLOSE <client_name> [misc. options] [targets]"\
109 "\n\tDeletes (closes) a session from specified client to server\n"
111 #define SESSION_ENUM_DISPLAY \
112 "Computer User name Client Type Opens Idle time\n\n"\
113 "------------------------------------------------------------------------------\n"
116 #define SESSION_DISPLAY_ONE \
117 "User name %-20.20s\n"\
118 "Computer %-20.20s\n"\
119 "Guest logon %-20.20s\n"\
120 "Client Type %-40.40s\n"\
121 "Sess time %2.2d:%2.2d:%2.2d\n"\
122 "Idle time %2.2d:%2.2d:%2.2d\n"
124 #define SESSION_DISPLAY_CONNS \
125 "Share name Type # Opens\n"\
126 "------------------------------------------------------------------------------\n"
128 #define NET_SERVER_USAGE \
130 " net server [domain]\tlists the servers in the specified domain or workgroup.\n"\
131 " If domain is not specified, it uses the current domain or workgroup as\n"\
134 #define SERVER_ENUM_DISPLAY "\nEnumerating servers in this domain or workgroup: \n\n" \
135 "\n\tServer name Server description\n"\
136 "\t------------- ----------------------------\n"
139 #define NET_DOMAIN_USAGE \
141 " net domain [misc. options] [target]\n\tlists the domains "\
142 "or workgroups visible on the current network\n"
144 #define DOMAIN_ENUM_DISPLAY \
145 "\nEnumerating domains:\n\n"\
146 "\n\tDomain name Server name of Browse Master\n"\
147 "\t------------- ----------------------------\n"
149 #define NET_PRINTQ_USAGE \
151 " net printq [misc. options] [targets]\n"\
153 " net printq list [<queue_name>] [misc. options] [targets]\n"\
154 "\tlists the specified queue and jobs on the target server.\n"\
155 "\tIf the queue name is not specified, all queues are listed.\n\n"\
156 " net printq delete [<queue name>] [misc. options] [targets]\n"\
157 "\tdeletes the specified job number on the target server, or the\n"\
158 "\tprinter queue if no job number is specified\n"
159 #define PRINTQ_ENUM_DISPLAY \
160 "Print queues at \\\\%s\n\n"\
161 "Name Job # Size Status\n\n"\
162 "------------------------------------------------------------------"\
164 #define PRINTQ_DISPLAY_ONE "%-23.23s %5d jobs %-22.22s\n"
165 #define PRINTQ_PRINTER_ACTIVE "*Printer Active*"
166 #define PRINTQ_PRINTER_PAUSED "*Printer Paused*"
167 #define PRINTQ_PRINTER_ERROR "*Printer error*"
168 #define PRINTQ_PRINTER_DELPEND "*Delete Pending*"
169 #define PRINTQ_PRINTER_STATUNK "**UNKNOWN STATUS**"
170 #define PRINTQ_DISPLAY_JOB " %-23.23s %5d %9d %-22.22s\n"
171 #define PRINTQ_JOB_PRINTING "Printing"
172 #define PRINTQ_JOB_QUEUED "Waiting"
173 #define PRINTQ_JOB_PAUSED "Held in queue"
174 #define PRINTQ_JOB_SPOOLING "Spooling"
175 #define PRINTQ_QUEUE_WORD " Queue"
177 #define NET_USER_USAGE \
178 "\nnet user [misc. options] [targets]\n\tEnumerate users\n"\
179 "\nnet user DELETE <name> [misc. options] [targets]"\
180 "\n\tDelete specified user\n"\
181 "\nnet user INFO <name> [misc. options] [targets]"\
182 "\n\tList the domain groups of the specified user\n"\
183 "\nnet user ADD <name> [-F user flags] [misc. options] [targets]"\
184 "\n\tAdd specified user\n"
186 #define USER_ENUM_DISPLAY \
187 "\nEnumerating shared resources (exports) on remote server:\n\n"\
188 "\nUser name Description Home Directory Profile Directory\n"\
189 "--------- ----------- -------------- -----------------\n"
191 #define NET_GROUP_USAGE \
192 "\nnet group [misc. options] [targets]"\
193 "\n\tEnumerate user groups\n"\
194 "\nnet group DELETE <name> [misc. options] [targets]"\
195 "\n\tDelete specified group\n"\
196 "\nnet group ADD <name> [-C comment] [misc. options] [targets]"\
197 "\n\tCreate specified group\n"
199 #define NET_GROUPMEMBER_USAGE \
200 "\nnet groupmember LIST <group name> [misc. options] [targets]"\
201 "\n\t Enumerate users in a group\n"\
202 "\nnet groupmember DELETE <group name> <user name> [misc. options] "\
203 "[targets]\n\t Delete sepcified user from specified group\n"\
204 "\nnet groupmember ADD <group name> <user name> [misc. options] [targets]"\
205 "\n\t Add specified user to specified group\n"
208 #define NET_ADMIN_USAGE \
209 "\nnet admin <remote command to execute> [cmd arguments [environment]] [misc_options] [targets]\n"\
210 "\texecutes a remote command on an os/2 target server\n"
212 #define NET_PASSWORD_USAGE \
213 "\nnet password <user> <old password> <new password> [misc_options] [targets]\n"\
214 "\tchanges the password for the specified user on a remote server\n"
216 #define NET_SERVICE_USAGE \
217 "\nnet service [misc. options] [targets] \n"\
218 "\tenumerates all running service daemons on target server\n"\
219 "\nnet service ADD <name> [service startup arguments] [misc. options] [targets]"\
220 "\n\tStart named service on remote server\n"\
221 "\nnet service DELETE <name> [misc. options] [targets]\n"\
222 "\n\tStop named service on remote server\n"
225 #define NET_VALIDATE_USAGE \
226 "\nnet validate <username> [password]\n"\
227 "\tValidate user and password to check whether they can access target server or domain\n"
229 #define TARGET_USAGE "\nValid targets: choose one (none defaults to using the %s)\n"
230 #define GLBL_LCL_MASTER "global browsemaster or local browse master if that is not found"
231 #define DOMAIN_MASTER "local domain browse master"
232 #define LOCAL_HOST "localhost"
233 #define MISC_OPT_USAGE "\nValid miscellaneous options are:\n"
234 #define SERVER_USAGE "\t-S or --server=<server>\t\tserver name\n"
235 #define IPADDRESS_USAGE "\t-I or --ipaddress=<ipaddr>\tip address of target server\n"
236 #define PORT_USAGE "\t-p or --port=<port number>\tconnection port on target server\n"
237 #define WORKGROUP_USAGE "\t-w or --workgroup=<wg>\t\ttarget workgroup or domain name\n"
238 #define COMMENT_USAGE "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"
239 #define MYWORKGROUP_USAGE "\t-W or --myworkgroup=<wg>\tclient workgroup\n"
240 #define DEBUG_USAGE "\t-d or --debug=<level>\t\tdebug level (0-10)\n"
241 #define MYNAME_USAGE "\t-n or --myname=<name>\t\tclient name\n"
242 #define USER_USAGE "\t-U or --user=<name>\t\tuser name\n"
243 #define CONF_USAGE "\t-s or --conf=<path>\t\tpathname of smb.conf file\n"
244 #define JOBID_USAGE "\t-j or --jobid=<job id>\t\tjob id\n"
245 #define MAXUSERS_USAGE "\t-M or --maxusers=<num>\t\tmax users allowed for share\n"
246 #define LONG_USAGE "\t-l or --long\t\t\tDisplay full information\n"
248 #define ERRMSG_NOCONN_TARGET_SRVR "\nUnable to connect to target server\n"
249 #define ERRMSG_NOCONN_BROWSE_MSTR "\nUnable to connect to browse master\n"
250 #define ERRMSG_NOT_IMPLEMENTED "\nNot implemented\n"
251 #define ERRMSG_FILEID_MISSING "\nMissing fileid of file to close\n\n"
252 #define ERRMSG_GROUPNAME_MISSING "\n\nGroup name not specified\n"
253 #define ERRMSG_USERNAME_MISSING "\n\nUser name not specified\n"
254 #define ERRMSG_SHARENAME_MISSING "\n\nShare name not specified\n"
255 #define ERRMSG_TARGET_WG_NOT_VALID "\nTarget workgroup option not valid "\
256 "except on net server command, ignored"
257 #define ERRMSG_INVALID_HELP_OPTION "\nInvalid help option\n"
258 #define ERRMSG_INVALID_OPTION "\nInvalid option %c (%d)\n"
259 #define ERRMSG_INVALID_IPADDRESS "\nInvalid ip address specified\n"
260 #define ERRMSG_SPURIOUS_PARM "\nInvalid paramater ignored: %s\n"
261 #define ERRMSG_BOTH_SERVER_IPADDRESS "\nTarget server and IP address both "\
262 "specified. Do not set both at the same time. The target IP address was used\n"
263 #define ERRMSG_INVALID_DOMAIN_ACTION "\nInvalid action for NET DOMAIN command"\
264 " ignored. Only listing domains permitted.\n"
267 #define COMMENT_STR "Comment "
268 #define USER_STR "User name "
269 #define GROUP_STR "Group name "
270 #define SERVICE_STR "Service name"
271 #define HOMED_STR "Home directory "
272 #define LOGONS_STR "Logon script "
274 #define FLAGS_MASTER 1
277 static const char *share_type[] = {
284 /************************************************************************************/
285 /* end of internationalization section */
286 /************************************************************************************/
288 extern int optind, opterr, optopt;
289 extern struct in_addr ipzero;
291 static struct cli_state *cli;
292 static char *opt_requester_name;
293 static char *opt_host;
294 static char *opt_password;
295 static char *opt_user_name;
296 static char *opt_workgroup;
297 static int opt_long_list_entries;
299 static int opt_maxusers = -1;
300 static char *opt_comment = "";
301 static int opt_flags = -1;
302 static int opt_jobid;
303 static char *opt_target_workgroup;
305 static BOOL got_pass = False;
306 static BOOL have_ip = False;
307 static struct in_addr dest_ip;
310 run a function from a function table. If not found then
311 call the specified usage function
313 int net_run_function(int argc, const char **argv, struct functable *table,
314 int (*usage_fn)(void))
320 for (i=0; table[i].funcname; i++) {
321 if (StrCaseCmp(argv[0], table[i].funcname) == 0) {
322 return table[i].fn(argc-1, argv+1);
325 d_printf("No command: %s\n", argv[0]);
330 /****************************************************************************
331 connect to \\server\ipc$
332 ****************************************************************************/
333 static struct cli_state *connect_to_ipc(char *server)
336 struct nmb_name called, calling;
342 /* make a copy so we don't modify the global string 'service' */
343 safe_strcpy(servicename, "IPC$", sizeof(servicename)-1);
344 sharename = servicename;
345 if (*sharename == '\\') {
346 server = sharename+2;
347 sharename = strchr(server,'\\');
348 if (!sharename) return NULL;
354 return NULL; /* if ip addr specified, ascii version of ip address is used as host name */
359 make_nmb_name(&calling, opt_requester_name, 0x0);
360 make_nmb_name(&called , server, 0x20);
367 DEBUG(3,("Connecting to host=%s\\share=%s\n\n",
370 /* have to open a new connection */
371 if (!(c=cli_initialise(NULL)) || cli_set_port(c, opt_port) != opt_port ||
372 !cli_connect(c, server_n, &ip)) {
373 DEBUG(1,("Connection to %s failed\n", server_n));
377 c->protocol = PROTOCOL_NT1;
379 if (!cli_session_request(c, &calling, &called)) {
381 DEBUG(1,("session request to %s failed (%s)\n",
382 called.name, cli_errstr(c)));
385 if ((p=strchr(called.name, '.'))) {
389 if (strcmp(called.name, "*SMBSERVER")) {
390 make_nmb_name(&called , "*SMBSERVER", 0x20);
396 DEBUG(4,(" session request ok\n"));
398 if (!cli_negprot(c)) {
399 DEBUG(1,("protocol negotiation failed\n"));
406 char *pass = getpass(PASSWORD_PROMPT);
408 opt_password = strdup(pass);
412 if (!cli_session_setup(c, opt_user_name,
413 opt_password, strlen(opt_password),
414 opt_password, strlen(opt_password),
416 /* try again with a null username */
417 if (!cli_session_setup(c, "", "", 0, "", 0, opt_workgroup)) {
418 DEBUG(1,("session setup failed: %s\n", cli_errstr(c)));
423 DEBUG(3,("Anonymous login successful\n"));
426 DEBUG(4,(" session setup ok\n"));
427 if (!cli_send_tconX(c, sharename, "?????",
428 opt_password, strlen(opt_password)+1)) {
429 DEBUG(1,("tree connect failed: %s\n", cli_errstr(c)));
435 DEBUG(4,(" tconx ok\n"));
440 static BOOL make_ipc_connection(unsigned flags)
442 if (!opt_host && have_ip) {
443 opt_host = strdup(inet_ntoa(dest_ip));
444 } else if (!opt_host && (flags & FLAGS_DMB)) {
445 struct in_addr *ip_list;
447 char *our_workgroup = lp_workgroup();
448 struct in_addr msbrow_ip;
449 /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
450 if (!get_dmb_list(&ip_list,&addr_count)){
451 DEBUG(1,("Unable to resolve global master browser via name lookup"));
452 if (!resolve_name(our_workgroup, &msbrow_ip, 0x1D)) {
453 DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
463 } else if (!opt_host && (flags & FLAGS_MASTER)) {
464 char *temp_workgroup = lp_workgroup();
465 char our_workgroup[16];
466 struct in_addr brow_ips;
468 /* find target server based on workgroup or domain */
469 if((temp_workgroup == 0) || (temp_workgroup[0] == 0))
470 temp_workgroup = lp_workgroup(); /* by default enum our local workgroup or domain */
472 safe_strcpy(our_workgroup, temp_workgroup,15);
474 if (!resolve_name(our_workgroup, &brow_ips, 0x1D)) {
475 /* go looking for workgroups */
476 DEBUG(1,("Unable to resolve master browser via name lookup\n"));
483 extern struct in_addr loopback_ip;
484 dest_ip = loopback_ip;
488 if (!opt_host && !have_ip) {
489 DEBUG(1,("no server to connect to\n"));
493 opt_host = strdup(inet_ntoa(dest_ip));
496 cli = connect_to_ipc(opt_host);
498 d_printf(ERRMSG_NOCONN_TARGET_SRVR);
505 static int general_usage(void)
507 d_printf(TARGET_USAGE, LOCAL_HOST); /* target options */
508 d_printf(SERVER_USAGE);
509 d_printf(IPADDRESS_USAGE);
511 d_printf(MISC_OPT_USAGE); /* misc options */
512 d_printf(PORT_USAGE);
513 d_printf(MYWORKGROUP_USAGE);
514 d_printf(DEBUG_USAGE);
515 d_printf(MYNAME_USAGE);
516 d_printf(USER_USAGE);
517 d_printf(CONF_USAGE);
521 static int net_usage(void)
527 static int file_usage(void)
529 d_printf(NET_FILE_USAGE); /* command syntax */
538 /***************************************************************************
539 list info on an open file
540 ***************************************************************************/
541 static void file_fn(const char * pPath, const char * pUser, uint16 perms,
542 uint16 locks, uint32 id)
544 d_printf("\t%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
545 id, pUser, perms, locks, pPath);
548 static void one_file_fn(const char *pPath, const char *pUser, uint16 perms,
549 uint16 locks, uint32 id)
551 d_printf(FILE_INFO_DISPLAY, id, pUser, locks, pPath, perms);
555 static int net_file_close(int argc, const char **argv)
560 if (!make_ipc_connection(0)) return -1;
561 return cli_NetFileClose(cli, atoi(argv[0]));
564 static int net_file_info(int argc, const char **argv)
569 if (!make_ipc_connection(0)) return -1;
570 return cli_NetFileGetInfo(cli, atoi(argv[0]), one_file_fn);
573 static int net_file_user(int argc, const char **argv)
578 d_printf("net file user not implemented yet\n");
582 static int net_file(int argc, const char **argv)
584 struct functable func[] = {
585 {"CLOSE", net_file_close},
586 {"USER", net_file_user},
587 {"INFO", net_file_info},
592 if (!make_ipc_connection(0)) return -1;
594 /* list open files */
595 d_printf(FILE_ENUM_DISPLAY); /* file list header */
596 return cli_NetFileEnum(cli, NULL, NULL, file_fn);
599 return net_run_function(argc, argv, func, file_usage);
602 static int share_usage(void)
604 d_printf(NET_SHARE_USAGE); /* command syntax */
609 static void long_share_fn(const char *share_name, uint32 type, const char *comment, void *state)
611 d_printf("%-12.12s %-8.8s %-50.50s\n", share_name, share_type[type], comment);
614 static void share_fn(const char *share_name, uint32 type, const char *comment, void *state)
616 d_printf("%-12.12s\n", share_name);
619 static int net_share_delete(int argc, const char **argv)
622 d_printf(ERRMSG_SHARENAME_MISSING);
625 if (!make_ipc_connection(0)) return -1;
626 return cli_NetShareDelete(cli, argv[0]);
629 static int net_share_add(int argc, const char **argv)
631 RAP_SHARE_INFO_2 sinfo;
636 d_printf(ERRMSG_SHARENAME_MISSING);
640 if (!make_ipc_connection(0)) return -1;
642 sharename = strdup(argv[0]);
643 p = strchr(sharename, '=');
645 strlcpy(sinfo.share_name, sharename, sizeof(sinfo.share_name));
646 sinfo.reserved1 = '\0';
647 sinfo.share_type = 0;
648 sinfo.comment = opt_comment;
650 sinfo.maximum_users = opt_maxusers;
651 sinfo.active_users = 0;
653 memset(sinfo.password, '\0', sizeof(sinfo.password));
654 sinfo.reserved2 = '\0';
656 return cli_NetShareAdd(cli, &sinfo);
660 static int net_share(int argc, const char **argv)
662 struct functable func[] = {
663 {"DELETE", net_share_delete},
664 {"CLOSE", net_share_delete},
665 {"ADD", net_share_add},
670 if (!make_ipc_connection(0)) return -1;
671 if (opt_long_list_entries) {
672 d_printf(SHARE_ENUM_DISPLAY);
673 return cli_RNetShareEnum(cli, long_share_fn, NULL);
675 return cli_RNetShareEnum(cli, share_fn, NULL);
678 return net_run_function(argc, argv, func, share_usage);
682 static int session_usage(void)
684 d_printf(NET_SESSION_USAGE); /* command syntax */
690 static void list_sessions_func(char *wsname, char *username, uint16 conns,
691 uint16 opens, uint16 users, uint32 sess_time,
692 uint32 idle_time, uint32 user_flags, char *clitype)
694 int hrs = idle_time / 3600;
695 int min = (idle_time / 60) % 60;
696 int sec = idle_time % 60;
698 d_printf("\\\\%-18.18s %-20.20s %-18.18s %5d %2.2d:%2.2d:%2.2d\n",
699 wsname, username, clitype, opens, hrs, min, sec);
702 static void display_session_func(const char *wsname, const char *username, uint16 conns,
703 uint16 opens, uint16 users, uint32 sess_time,
704 uint32 idle_time, uint32 user_flags, const char *clitype)
706 int ihrs = idle_time / 3600;
707 int imin = (idle_time / 60) % 60;
708 int isec = idle_time % 60;
709 int shrs = sess_time / 3600;
710 int smin = (sess_time / 60) % 60;
711 int ssec = sess_time % 60;
712 d_printf(SESSION_DISPLAY_ONE, username, wsname,
713 (user_flags&0x0)?YES_STRING:NO_STRING, clitype,
714 shrs, smin, ssec, ihrs, imin, isec);
717 static void display_conns_func(uint16 conn_id, uint16 conn_type, uint16 opens, uint16 users, uint32 conn_time, const char *username, const char *netname)
719 d_printf("%-14.14s %-8.8s %5d\n", netname, share_type[conn_type], opens);
722 static int net_session_info(int argc, const char **argv)
725 const char *sessname;
727 if (!make_ipc_connection(0)) return -1;
729 if (argc == 0) return session_usage();
733 res = cli_NetSessionGetInfo(cli, sessname, display_session_func);
734 if (res < 0) return res;
736 d_printf(SESSION_DISPLAY_CONNS);
737 return cli_NetConnectionEnum(cli, sessname, display_conns_func);
740 static int net_session_delete(int argc, const char **argv)
742 if (!make_ipc_connection(0)) return -1;
744 if (argc == 0) return session_usage();
746 return cli_NetSessionDel(cli, argv[0]);
749 static int net_session(int argc, const char **argv)
751 struct functable func[] = {
752 {"INFO", net_session_info},
753 {"DELETE", net_session_delete},
754 {"CLOSE", net_session_delete},
759 if (!make_ipc_connection(0)) return -1;
760 return cli_NetSessionEnum(cli, list_sessions_func);
763 return net_run_function(argc, argv, func, session_usage);
766 /****************************************************************************
768 ****************************************************************************/
769 static void display_server_func(const char *name, uint32 m, const char *comment, void * reserved)
771 d_printf("\t%-16.16s %s\n", name, comment);
775 static int server_usage(void)
777 d_printf(NET_SERVER_USAGE); /* command syntax */
783 static int net_server(int argc, const char **argv)
785 if (!make_ipc_connection(FLAGS_MASTER)) return -1;
786 d_printf(SERVER_ENUM_DISPLAY); /* header for list of servers */
787 return cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, display_server_func,NULL);
790 static int domain_usage(void)
792 d_printf(NET_DOMAIN_USAGE); /* command syntax */
799 static int net_domain(int argc, const char **argv)
801 if (!make_ipc_connection(FLAGS_DMB)) return -1;
802 d_printf(DOMAIN_ENUM_DISPLAY); /* header for list of domains */
803 return cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, display_server_func,NULL);
806 static int printq_usage(void)
808 d_printf(NET_PRINTQ_USAGE);
814 static void enum_queue(const char *queuename, uint16 pri, uint16 start, uint16 until,
815 const char *sep, const char *pproc, const char *dest,
816 const char *qparms, const char *qcomment, uint16 status,
821 pstrcpy(queuecol, queuename);
822 pstrcat(queuecol, PRINTQ_QUEUE_WORD);
826 pstrcpy(statcol, PRINTQ_PRINTER_ACTIVE);
829 pstrcpy(statcol, PRINTQ_PRINTER_PAUSED);
832 pstrcpy(statcol, PRINTQ_PRINTER_ERROR);
835 pstrcpy(statcol, PRINTQ_PRINTER_DELPEND);
838 pstrcpy(statcol, PRINTQ_PRINTER_STATUNK);
840 d_printf(PRINTQ_DISPLAY_ONE, queuecol, jobcount, statcol);
843 static void enum_jobs(uint16 jobid, const char *ownername, const char *notifyname,
844 const char *datatype, const char *jparms, uint16 pos,
845 uint16 status, const char *jstatus, uint submitted, uint jobsize,
846 const char *comment) {
851 pstrcpy(statcol, PRINTQ_JOB_QUEUED);
854 pstrcpy(statcol, PRINTQ_JOB_PAUSED);
857 pstrcpy(statcol, PRINTQ_JOB_SPOOLING);
860 pstrcpy(statcol, PRINTQ_JOB_PRINTING);
863 pstrcpy(statcol, PRINTQ_PRINTER_STATUNK);
865 d_printf(PRINTQ_DISPLAY_JOB, ownername, jobid, jobsize, statcol);
868 static int net_printq_info(int argc, const char **argv)
870 if (argc == 0) return printq_usage();
872 if (!make_ipc_connection(0)) return -1;
874 return cli_NetPrintQGetInfo(cli, argv[0], enum_queue, enum_jobs);
877 static int net_printq_delete(int argc, const char **argv)
879 if (argc == 0) return printq_usage();
881 if (!make_ipc_connection(0)) return -1;
883 return cli_printjob_del(cli, atoi(argv[0]));
886 static int net_printq(int argc, const char **argv)
888 struct functable func[] = {
889 {"INFO", net_printq_info},
890 {"DELETE", net_printq_delete},
895 if (!make_ipc_connection(0)) return -1;
896 return cli_NetPrintQEnum(cli, enum_queue, enum_jobs);
899 return net_run_function(argc, argv, func, printq_usage);
903 static int user_usage(void)
905 d_printf(NET_USER_USAGE); /* command syntax */
911 static void user_fn(const char *user_name, const char *comment, const char * home_dir,
912 const char * logon_script, void *state)
914 d_printf("%-21.21s\n", user_name);
917 void long_user_fn(const char *user_name, const char *comment, const char * home_dir, const char * logon_script, void *state)
919 d_printf("%-21.21s %-47.47s %-35.35s %35.35s\n", user_name, comment, home_dir, logon_script);
922 void group_member_fn(const char *user_name, void *state)
924 d_printf("%-21.21s\n", user_name);
927 static int net_user_delete(int argc, const char **argv)
929 if (argc == 0) return user_usage();
931 if (!make_ipc_connection(0)) return -1;
933 return cli_NetUserDelete(cli, argv[0]);
936 static int net_user_add(int argc, const char **argv)
938 RAP_USER_INFO_1 userinfo;
940 if (argc == 0) return user_usage();
942 if (!make_ipc_connection(0)) return -1;
944 safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name));
945 if (opt_flags == -1) opt_flags = 0x21;
947 userinfo.userflags = opt_flags;
948 userinfo.reserved1 = '\0';
949 userinfo.comment = opt_comment;
951 userinfo.home_dir = NULL;
952 userinfo.logon_script = NULL;
954 return cli_NetUserAdd(cli, &userinfo);
957 static int net_user_info(int argc, const char **argv)
959 if (argc == 0) return user_usage();
961 if (!make_ipc_connection(0)) return -1;
963 return cli_NetUserGetGroups(cli, argv[0], group_member_fn, NULL);
966 int net_user(int argc, const char **argv)
968 struct functable func[] = {
969 {"ADD", net_user_add},
970 {"INFO", net_user_info},
971 {"DELETE", net_user_delete},
976 if (!make_ipc_connection(0)) return -1;
977 if (opt_long_list_entries) {
978 d_printf(USER_ENUM_DISPLAY);
979 return cli_RNetUserEnum(cli, long_user_fn, NULL);
981 return cli_RNetUserEnum(cli, user_fn, NULL);
984 return net_run_function(argc, argv, func, user_usage);
988 static int group_usage(void)
990 d_printf(NET_GROUP_USAGE); /* command syntax */
996 static void long_group_fn(const char *group_name, const char *comment, void *state)
998 d_printf("%-21.21s %-50.50s\n", group_name, comment);
1001 static void group_fn(const char *group_name, const char *comment, void *state)
1003 d_printf("%-21.21s\n", group_name);
1006 static int net_group_delete(int argc, const char **argv)
1008 if (argc == 0) return group_usage();
1009 if (!make_ipc_connection(0)) return -1;
1010 return cli_NetGroupDelete(cli, argv[0]);
1013 static int net_group_add(int argc, const char **argv)
1015 RAP_GROUP_INFO_1 grinfo;
1017 if (argc == 0) return group_usage();
1018 if (!make_ipc_connection(0)) return -1;
1020 /* BB check for length 21 or smaller explicitly ? BB */
1021 safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name));
1022 grinfo.reserved1 = '\0';
1023 grinfo.comment = opt_comment;
1025 return cli_NetGroupAdd(cli, &grinfo);
1028 static int net_group(int argc, const char **argv)
1030 struct functable func[] = {
1031 {"ADD", net_group_add},
1032 {"DELETE", net_group_delete},
1037 if (!make_ipc_connection(0)) return -1;
1038 if (opt_long_list_entries) {
1039 d_printf("%-21.21s %-50.50s\n", GROUP_STR, COMMENT_STR);
1040 d_printf("-----------------------------\n");
1041 return cli_RNetGroupEnum(cli, long_group_fn, NULL);
1043 return cli_RNetGroupEnum(cli, group_fn, NULL);
1046 return net_run_function(argc, argv, func, group_usage);
1049 static int groupmember_usage(void)
1051 d_printf(NET_GROUPMEMBER_USAGE); /* command syntax */
1058 static int net_groupmember_add(int argc, const char **argv)
1060 if (argc != 2) return groupmember_usage();
1062 if (!make_ipc_connection(0)) return -1;
1064 return cli_NetGroupAddUser(cli, argv[0], argv[1]);
1067 static int net_groupmember_delete(int argc, const char **argv)
1069 if (argc != 2) return groupmember_usage();
1071 if (!make_ipc_connection(0)) return -1;
1073 return cli_NetGroupDelUser(cli, argv[0], argv[1]);
1076 static int net_groupmember_list(int argc, const char **argv)
1078 if (argc == 0) return groupmember_usage();
1080 if (!make_ipc_connection(0)) return -1;
1082 return cli_NetGroupGetUsers(cli, argv[0], group_member_fn, NULL );
1085 static int net_groupmember(int argc, const char **argv)
1087 struct functable func[] = {
1088 {"ADD", net_groupmember_add},
1089 {"LIST", net_groupmember_list},
1090 {"DELETE", net_groupmember_delete},
1094 return net_run_function(argc, argv, func, groupmember_usage);
1097 static int validate_usage(void)
1099 d_printf(NET_VALIDATE_USAGE); /* command syntax */
1105 static int net_validate(int argc, const char **argv)
1107 d_printf(ERRMSG_NOT_IMPLEMENTED);
1111 static int service_usage(void)
1113 d_printf(NET_SERVICE_USAGE); /* command syntax */
1119 static int net_service_add(int argc, const char **argv)
1121 d_printf(ERRMSG_NOT_IMPLEMENTED);
1125 static int net_service_delete(int argc, const char **argv)
1127 d_printf(ERRMSG_NOT_IMPLEMENTED);
1131 static int net_service(int argc, const char **argv)
1133 struct functable func[] = {
1134 {"ADD", net_service_add},
1135 {"DELETE", net_service_delete},
1140 if (!make_ipc_connection(0)) return -1;
1141 if (opt_long_list_entries) {
1142 d_printf("%-15.15s %-50.50s\n", SERVICE_STR, COMMENT_STR);
1143 d_printf("-----------------------------\n");
1144 return cli_RNetServiceEnum(cli, long_group_fn, NULL);
1146 return cli_RNetServiceEnum(cli, group_fn, NULL);
1149 return net_run_function(argc, argv, func, service_usage);
1152 static int password_usage(void)
1154 d_printf(NET_PASSWORD_USAGE); /* command syntax */
1161 static int net_password(int argc, const char **argv)
1163 if (argc < 3) return password_usage();
1165 if (!make_ipc_connection(0)) return -1;
1167 /* BB Add check for password lengths? */
1168 return cli_oem_change_password(cli, argv[0], argv[2], argv[1]);
1171 static int admin_usage(void)
1173 d_printf(NET_ADMIN_USAGE); /* command syntax */
1180 static int net_admin(int argc, const char **argv)
1182 d_printf(ERRMSG_NOT_IMPLEMENTED);
1186 static int help_usage(void)
1189 "Usage: net help <function>\n"\
1191 "Valid functions are:\n"\
1192 " FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP\n"\
1193 " VALIDATE GROUPMEMBER ADMIN SERVICE PASSWORD ADS\n");
1198 handle "net help *" subcommands
1200 static int net_help(int argc, const char **argv)
1202 struct functable func[] = {
1203 {"FILE", file_usage},
1204 {"SHARE", share_usage},
1205 {"SESSION", session_usage},
1206 {"SERVER", server_usage},
1207 {"DOMAIN", domain_usage},
1208 {"PRINTQ", printq_usage},
1209 {"USER", user_usage},
1210 {"GROUP", group_usage},
1211 {"VALIDATE", validate_usage},
1212 {"GROUPMEMBER", groupmember_usage},
1213 {"ADMIN", admin_usage},
1214 {"SERVICE", service_usage},
1215 {"PASSWORD", password_usage},
1216 {"ADS", net_ads_usage},
1219 return net_run_function(argc, argv, func, help_usage);
1222 /* main function table */
1223 static struct functable net_func[] = {
1225 {"SHARE", net_share},
1226 {"SESSION", net_session},
1227 {"SERVER", net_server},
1228 {"DOMAIN", net_domain},
1229 {"PRINTQ", net_printq},
1231 {"GROUP", net_group},
1232 {"VALIDATE", net_validate},
1233 {"GROUPMEMBER", net_groupmember},
1234 {"ADMIN", net_admin},
1235 {"SERVICE", net_service},
1236 {"PASSWORD", net_password},
1243 /****************************************************************************
1245 ****************************************************************************/
1246 int main(int argc,char *argv[])
1252 const char ** argv_new;
1254 static char *servicesf = dyn_CONFIGFILE;
1255 extern pstring global_myname;
1256 static int debuglevel;
1258 struct poptOption long_options[] = {
1259 {"help", 'h', POPT_ARG_NONE, 0, 'h'},
1260 {"workgroup", 'w', POPT_ARG_STRING, &opt_target_workgroup},
1261 {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup},
1262 {"user", 'U', POPT_ARG_STRING, &opt_user_name, 'U'},
1263 {"ipaddress", 'I', POPT_ARG_STRING, 0, 'I'},
1264 {"port", 'p', POPT_ARG_INT, &opt_port},
1265 {"myname", 'n', POPT_ARG_STRING, &opt_requester_name},
1266 {"conf", 's', POPT_ARG_STRING, &servicesf},
1267 {"debug", 'd', POPT_ARG_INT, &debuglevel, 'd'},
1268 {"debuglevel", 'd', POPT_ARG_INT, &debuglevel, 'd'},
1269 {"server", 'S', POPT_ARG_STRING, &opt_host},
1270 {"comment", 'C', POPT_ARG_STRING, &opt_comment},
1271 {"maxusers", 'M', POPT_ARG_INT, &opt_maxusers},
1272 {"flags", 'F', POPT_ARG_INT, &opt_flags},
1273 {"jobid", 'j', POPT_ARG_INT, &opt_jobid},
1274 {"long", 'l', POPT_ARG_NONE, &opt_long_list_entries},
1283 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
1284 POPT_CONTEXT_KEEP_FIRST);
1286 while((opt = poptGetNextOpt(pc)) != -1) {
1293 dest_ip = *interpret_addr2(poptGetOptArg(pc));
1294 if (zero_ip(dest_ip))
1295 d_printf(ERRMSG_INVALID_IPADDRESS);
1300 opt_user_name = strdup(opt_user_name);
1301 p = strchr(opt_user_name,'%');
1309 d_printf(ERRMSG_INVALID_OPTION, (char)opt, opt);
1314 DEBUGLEVEL = debuglevel;
1316 lp_load(servicesf,True,False,False);
1318 argv_new = (const char **)poptGetArgs(pc);
1321 for (i=0; i<argc; i++) {
1322 if (argv_new[i] == NULL) {
1328 if (!opt_requester_name) {
1329 static fstring myname;
1331 opt_requester_name = myname;
1334 if (!opt_user_name && getenv("LOGNAME")) {
1335 opt_user_name = getenv("LOGNAME");
1338 if (!opt_workgroup) {
1339 opt_workgroup = lp_workgroup();
1342 if (!*global_myname) {
1344 fstrcpy(global_myname, myhostname());
1345 p = strchr_m(global_myname, '.');
1351 rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage);
1353 DEBUG(2,("return code = %d\n", rc));