• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/utils/
1/*
2   Samba Unix/Linux SMB client library
3   net status command -- possible replacement for smbstatus
4   Copyright (C) 2003 Volker Lendecke (vl@samba.org)
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19#include "includes.h"
20#include "utils/net.h"
21
22int net_status_usage(struct net_context *c, int argc, const char **argv)
23{
24	d_printf(_("  net status sessions [parseable] "
25		   "Show list of open sessions\n"));
26	d_printf(_("  net status shares [parseable]   "
27		   "Show list of open shares\n"));
28	return -1;
29}
30
31static int show_session(struct db_record *rec, void *private_data)
32{
33	bool *parseable = (bool *)private_data;
34	struct sessionid sessionid;
35
36	if (rec->value.dsize != sizeof(sessionid))
37		return 0;
38
39	memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
40
41	if (!process_exists(sessionid.pid)) {
42		return 0;
43	}
44
45	if (*parseable) {
46		d_printf("%s\\%s\\%s\\%s\\%s\n",
47			 procid_str_static(&sessionid.pid), uidtoname(sessionid.uid),
48			 gidtoname(sessionid.gid),
49			 sessionid.remote_machine, sessionid.hostname);
50	} else {
51		d_printf("%7s   %-12s  %-12s  %-12s (%s)\n",
52			 procid_str_static(&sessionid.pid), uidtoname(sessionid.uid),
53			 gidtoname(sessionid.gid),
54			 sessionid.remote_machine, sessionid.hostname);
55	}
56
57	return 0;
58}
59
60static int net_status_sessions(struct net_context *c, int argc, const char **argv)
61{
62	struct db_context *db;
63	bool parseable;
64
65	if (c->display_usage) {
66		d_printf(  "%s\n"
67			   "net status sessions [parseable]\n"
68			   "    %s\n",
69			 _("Usage:"),
70			 _("Display open user sessions.\n"
71			   "    If parseable is specified, output is machine-"
72			   "readable."));
73		return 0;
74	}
75
76	if (argc == 0) {
77		parseable = false;
78	} else if ((argc == 1) && strequal(argv[0], "parseable")) {
79		parseable = true;
80	} else {
81		return net_status_usage(c, argc, argv);
82	}
83
84	if (!parseable) {
85		d_printf(_("PID     Username      Group         Machine"
86			   "                        \n"
87		           "-------------------------------------------"
88			   "------------------------\n"));
89	}
90
91	db = db_open(NULL, lock_path("sessionid.tdb"), 0,
92		     TDB_CLEAR_IF_FIRST, O_RDONLY, 0644);
93	if (db == NULL) {
94		d_fprintf(stderr, _("%s not initialised\n"),
95			  lock_path("sessionid.tdb"));
96		return -1;
97	}
98
99	db->traverse_read(db, show_session, &parseable);
100	TALLOC_FREE(db);
101
102	return 0;
103}
104
105static int show_share(struct db_record *rec,
106		      const struct connections_key *key,
107		      const struct connections_data *crec,
108		      void *state)
109{
110	if (crec->cnum == -1)
111		return 0;
112
113	if (!process_exists(crec->pid)) {
114		return 0;
115	}
116
117	d_printf("%-10.10s   %s   %-12s  %s",
118	       crec->servicename, procid_str_static(&crec->pid),
119	       crec->machine,
120	       time_to_asc(crec->start));
121
122	return 0;
123}
124
125struct sessionids {
126	int num_entries;
127	struct sessionid *entries;
128};
129
130static int collect_pid(struct db_record *rec, void *private_data)
131{
132	struct sessionids *ids = (struct sessionids *)private_data;
133	struct sessionid sessionid;
134
135	if (rec->value.dsize != sizeof(sessionid))
136		return 0;
137
138	memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
139
140	if (!process_exists(sessionid.pid))
141		return 0;
142
143	ids->num_entries += 1;
144	ids->entries = SMB_REALLOC_ARRAY(ids->entries, struct sessionid, ids->num_entries);
145	if (!ids->entries) {
146		ids->num_entries = 0;
147		return 0;
148	}
149	ids->entries[ids->num_entries-1] = sessionid;
150
151	return 0;
152}
153
154static int show_share_parseable(struct db_record *rec,
155				const struct connections_key *key,
156				const struct connections_data *crec,
157				void *state)
158{
159	struct sessionids *ids = (struct sessionids *)state;
160	int i;
161	bool guest = true;
162
163	if (crec->cnum == -1)
164		return 0;
165
166	if (!process_exists(crec->pid)) {
167		return 0;
168	}
169
170	for (i=0; i<ids->num_entries; i++) {
171		struct server_id id = ids->entries[i].pid;
172		if (procid_equal(&id, &crec->pid)) {
173			guest = false;
174			break;
175		}
176	}
177
178	d_printf("%s\\%s\\%s\\%s\\%s\\%s\\%s",
179		 crec->servicename,procid_str_static(&crec->pid),
180		 guest ? "" : uidtoname(ids->entries[i].uid),
181		 guest ? "" : gidtoname(ids->entries[i].gid),
182		 crec->machine,
183		 guest ? "" : ids->entries[i].hostname,
184		 time_to_asc(crec->start));
185
186	return 0;
187}
188
189static int net_status_shares_parseable(struct net_context *c, int argc, const char **argv)
190{
191	struct sessionids ids;
192	struct db_context *db;
193
194	ids.num_entries = 0;
195	ids.entries = NULL;
196
197	db = db_open(NULL, lock_path("sessionid.tdb"), 0,
198		     TDB_CLEAR_IF_FIRST, O_RDONLY, 0644);
199	if (db == NULL) {
200		d_fprintf(stderr, _("%s not initialised\n"),
201			  lock_path("sessionid.tdb"));
202		return -1;
203	}
204
205	db->traverse_read(db, collect_pid, &ids);
206	TALLOC_FREE(db);
207
208	connections_forall(show_share_parseable, &ids);
209
210	SAFE_FREE(ids.entries);
211
212	return 0;
213}
214
215static int net_status_shares(struct net_context *c, int argc, const char **argv)
216{
217	if (c->display_usage) {
218		d_printf(  "%s\n"
219			   "net status shares [parseable]\n"
220			   "    %s\n",
221			 _("Usage:"),
222			 _("Display open user shares.\n"
223			   "    If parseable is specified, output is machine-"
224			   "readable."));
225		return 0;
226	}
227
228	if (argc == 0) {
229
230		d_printf(_("\nService      pid     machine       "
231			   "Connected at\n"
232		           "-------------------------------------"
233			   "------------------\n"));
234
235		connections_forall(show_share, NULL);
236
237		return 0;
238	}
239
240	if ((argc != 1) || !strequal(argv[0], "parseable")) {
241		return net_status_usage(c, argc, argv);
242	}
243
244	return net_status_shares_parseable(c, argc, argv);
245}
246
247int net_status(struct net_context *c, int argc, const char **argv)
248{
249	struct functable func[] = {
250		{
251			"sessions",
252			net_status_sessions,
253			NET_TRANSPORT_LOCAL,
254			N_("Show list of open sessions"),
255			N_("net status sessions [parseable]\n"
256			   "    If parseable is specified, output is presented "
257			   "in a machine-parseable fashion.")
258		},
259		{
260			"shares",
261			net_status_shares,
262			NET_TRANSPORT_LOCAL,
263			N_("Show list of open shares"),
264			N_("net status shares [parseable]\n"
265			   "    If parseable is specified, output is presented "
266			   "in a machine-parseable fashion.")
267		},
268		{NULL, NULL, 0, NULL, NULL}
269	};
270	return net_run_function(c, argc, argv, "net status", func);
271}
272