Line data Source code
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 "lib/util/server_id.h"
21 : #include "utils/net.h"
22 : #include "session.h"
23 : #include "messages.h"
24 : #include "conn_tdb.h"
25 :
26 0 : int net_status_usage(struct net_context *c, int argc, const char **argv)
27 : {
28 0 : d_printf(_(" net status sessions [parseable] "
29 : "Show list of open sessions\n"));
30 0 : d_printf(_(" net status shares [parseable] "
31 : "Show list of open shares\n"));
32 0 : return -1;
33 : }
34 :
35 0 : static int show_session(const char *key, struct sessionid *session,
36 : void *private_data)
37 : {
38 0 : struct server_id_buf tmp;
39 0 : bool *parseable = (bool *)private_data;
40 :
41 0 : if (!process_exists(session->pid)) {
42 0 : return 0;
43 : }
44 :
45 0 : if (*parseable) {
46 0 : d_printf("%s\\%s\\%s\\%s\\%s\n",
47 : server_id_str_buf(session->pid, &tmp),
48 : uidtoname(session->uid),
49 : gidtoname(session->gid),
50 0 : session->remote_machine, session->hostname);
51 : } else {
52 0 : d_printf("%7s %-12s %-12s %-12s (%s)\n",
53 : server_id_str_buf(session->pid, &tmp),
54 : uidtoname(session->uid),
55 : gidtoname(session->gid),
56 0 : session->remote_machine, session->hostname);
57 : }
58 :
59 0 : return 0;
60 : }
61 :
62 0 : static int net_status_sessions(struct net_context *c, int argc, const char **argv)
63 : {
64 0 : bool parseable;
65 :
66 0 : if (c->display_usage) {
67 0 : d_printf( "%s\n"
68 : "net status sessions [parseable]\n"
69 : " %s\n",
70 : _("Usage:"),
71 : _("Display open user sessions.\n"
72 : " If parseable is specified, output is machine-"
73 : "readable."));
74 0 : return 0;
75 : }
76 :
77 0 : if (argc == 0) {
78 0 : parseable = false;
79 0 : } else if ((argc == 1) && strequal(argv[0], "parseable")) {
80 0 : parseable = true;
81 : } else {
82 0 : return net_status_usage(c, argc, argv);
83 : }
84 :
85 0 : if (!parseable) {
86 0 : d_printf(_("PID Username Group Machine"
87 : " \n"
88 : "-------------------------------------------"
89 : "------------------------\n"));
90 : }
91 :
92 0 : sessionid_traverse_read(show_session, &parseable);
93 0 : return 0;
94 : }
95 :
96 0 : static int show_share(const struct connections_data *crec,
97 : void *state)
98 : {
99 0 : struct server_id_buf tmp;
100 :
101 0 : if (crec->cnum == TID_FIELD_INVALID)
102 0 : return 0;
103 :
104 0 : if (!process_exists(crec->pid)) {
105 0 : return 0;
106 : }
107 :
108 0 : d_printf("%-10.10s %s %-12s %s",
109 0 : crec->servicename, server_id_str_buf(crec->pid, &tmp),
110 0 : crec->machine,
111 0 : time_to_asc(nt_time_to_unix(crec->start)));
112 :
113 0 : return 0;
114 : }
115 :
116 : struct sessionids {
117 : int num_entries;
118 : struct sessionid *entries;
119 : };
120 :
121 0 : static int collect_pids(const char *key, struct sessionid *session,
122 : void *private_data)
123 : {
124 0 : struct sessionids *ids = (struct sessionids *)private_data;
125 :
126 0 : if (!process_exists(session->pid))
127 0 : return 0;
128 :
129 0 : ids->num_entries += 1;
130 0 : ids->entries = SMB_REALLOC_ARRAY(ids->entries, struct sessionid, ids->num_entries);
131 0 : if (!ids->entries) {
132 0 : ids->num_entries = 0;
133 0 : return 0;
134 : }
135 0 : ids->entries[ids->num_entries-1] = *session;
136 :
137 0 : return 0;
138 : }
139 :
140 0 : static int show_share_parseable(const struct connections_data *crec,
141 : void *state)
142 : {
143 0 : struct sessionids *ids = (struct sessionids *)state;
144 0 : struct server_id_buf tmp;
145 0 : int i;
146 0 : bool guest = true;
147 :
148 0 : if (crec->cnum == TID_FIELD_INVALID)
149 0 : return 0;
150 :
151 0 : if (!process_exists(crec->pid)) {
152 0 : return 0;
153 : }
154 :
155 0 : for (i=0; i<ids->num_entries; i++) {
156 0 : struct server_id id = ids->entries[i].pid;
157 0 : if (server_id_equal(&id, &crec->pid)) {
158 0 : guest = false;
159 0 : break;
160 : }
161 : }
162 :
163 0 : d_printf("%s\\%s\\%s\\%s\\%s\\%s\\%s",
164 0 : crec->servicename, server_id_str_buf(crec->pid, &tmp),
165 0 : guest ? "" : uidtoname(ids->entries[i].uid),
166 0 : guest ? "" : gidtoname(ids->entries[i].gid),
167 0 : crec->machine,
168 0 : guest ? "" : ids->entries[i].hostname,
169 0 : time_to_asc(nt_time_to_unix(crec->start)));
170 :
171 0 : return 0;
172 : }
173 :
174 0 : static int net_status_shares_parseable(struct net_context *c, int argc, const char **argv)
175 : {
176 0 : struct sessionids ids;
177 :
178 0 : ids.num_entries = 0;
179 0 : ids.entries = NULL;
180 :
181 0 : sessionid_traverse_read(collect_pids, &ids);
182 :
183 0 : connections_forall_read(show_share_parseable, &ids);
184 :
185 0 : SAFE_FREE(ids.entries);
186 :
187 0 : return 0;
188 : }
189 :
190 0 : static int net_status_shares(struct net_context *c, int argc, const char **argv)
191 : {
192 0 : if (c->display_usage) {
193 0 : d_printf( "%s\n"
194 : "net status shares [parseable]\n"
195 : " %s\n",
196 : _("Usage:"),
197 : _("Display open user shares.\n"
198 : " If parseable is specified, output is machine-"
199 : "readable."));
200 0 : return 0;
201 : }
202 :
203 0 : if (argc == 0) {
204 :
205 0 : d_printf(_("\nService pid machine "
206 : "Connected at\n"
207 : "-------------------------------------"
208 : "------------------\n"));
209 :
210 0 : connections_forall_read(show_share, NULL);
211 :
212 0 : return 0;
213 : }
214 :
215 0 : if ((argc != 1) || !strequal(argv[0], "parseable")) {
216 0 : return net_status_usage(c, argc, argv);
217 : }
218 :
219 0 : return net_status_shares_parseable(c, argc, argv);
220 : }
221 :
222 0 : int net_status(struct net_context *c, int argc, const char **argv)
223 : {
224 0 : struct functable func[] = {
225 : {
226 : "sessions",
227 : net_status_sessions,
228 : NET_TRANSPORT_LOCAL,
229 : N_("Show list of open sessions"),
230 : N_("net status sessions [parseable]\n"
231 : " If parseable is specified, output is presented "
232 : "in a machine-parseable fashion.")
233 : },
234 : {
235 : "shares",
236 : net_status_shares,
237 : NET_TRANSPORT_LOCAL,
238 : N_("Show list of open shares"),
239 : N_("net status shares [parseable]\n"
240 : " If parseable is specified, output is presented "
241 : "in a machine-parseable fashion.")
242 : },
243 : {NULL, NULL, 0, NULL, NULL}
244 : };
245 0 : return net_run_function(c, argc, argv, "net status", func);
246 : }
|