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 : 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 : 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_key *key,
97 : const struct connections_data *crec,
98 : void *state)
99 : {
100 : struct server_id_buf tmp;
101 :
102 0 : if (crec->cnum == TID_FIELD_INVALID)
103 0 : return 0;
104 :
105 0 : if (!process_exists(crec->pid)) {
106 0 : return 0;
107 : }
108 :
109 0 : d_printf("%-10.10s %s %-12s %s",
110 0 : crec->servicename, server_id_str_buf(crec->pid, &tmp),
111 0 : crec->machine,
112 0 : time_to_asc(crec->start));
113 :
114 0 : return 0;
115 : }
116 :
117 : struct sessionids {
118 : int num_entries;
119 : struct sessionid *entries;
120 : };
121 :
122 0 : static int collect_pids(const char *key, struct sessionid *session,
123 : void *private_data)
124 : {
125 0 : struct sessionids *ids = (struct sessionids *)private_data;
126 :
127 0 : if (!process_exists(session->pid))
128 0 : return 0;
129 :
130 0 : ids->num_entries += 1;
131 0 : ids->entries = SMB_REALLOC_ARRAY(ids->entries, struct sessionid, ids->num_entries);
132 0 : if (!ids->entries) {
133 0 : ids->num_entries = 0;
134 0 : return 0;
135 : }
136 0 : ids->entries[ids->num_entries-1] = *session;
137 :
138 0 : return 0;
139 : }
140 :
141 0 : static int show_share_parseable(const struct connections_key *key,
142 : const struct connections_data *crec,
143 : void *state)
144 : {
145 0 : struct sessionids *ids = (struct sessionids *)state;
146 : struct server_id_buf tmp;
147 : int i;
148 0 : bool guest = true;
149 :
150 0 : if (crec->cnum == TID_FIELD_INVALID)
151 0 : return 0;
152 :
153 0 : if (!process_exists(crec->pid)) {
154 0 : return 0;
155 : }
156 :
157 0 : for (i=0; i<ids->num_entries; i++) {
158 0 : struct server_id id = ids->entries[i].pid;
159 0 : if (server_id_equal(&id, &crec->pid)) {
160 0 : guest = false;
161 0 : break;
162 : }
163 : }
164 :
165 0 : d_printf("%s\\%s\\%s\\%s\\%s\\%s\\%s",
166 0 : crec->servicename, server_id_str_buf(crec->pid, &tmp),
167 0 : guest ? "" : uidtoname(ids->entries[i].uid),
168 0 : guest ? "" : gidtoname(ids->entries[i].gid),
169 0 : crec->machine,
170 0 : guest ? "" : ids->entries[i].hostname,
171 0 : time_to_asc(crec->start));
172 :
173 0 : return 0;
174 : }
175 :
176 0 : static int net_status_shares_parseable(struct net_context *c, int argc, const char **argv)
177 : {
178 : struct sessionids ids;
179 :
180 0 : ids.num_entries = 0;
181 0 : ids.entries = NULL;
182 :
183 0 : sessionid_traverse_read(collect_pids, &ids);
184 :
185 0 : connections_forall_read(show_share_parseable, &ids);
186 :
187 0 : SAFE_FREE(ids.entries);
188 :
189 0 : return 0;
190 : }
191 :
192 0 : static int net_status_shares(struct net_context *c, int argc, const char **argv)
193 : {
194 0 : if (c->display_usage) {
195 0 : d_printf( "%s\n"
196 : "net status shares [parseable]\n"
197 : " %s\n",
198 : _("Usage:"),
199 : _("Display open user shares.\n"
200 : " If parseable is specified, output is machine-"
201 : "readable."));
202 0 : return 0;
203 : }
204 :
205 0 : if (argc == 0) {
206 :
207 0 : d_printf(_("\nService pid machine "
208 : "Connected at\n"
209 : "-------------------------------------"
210 : "------------------\n"));
211 :
212 0 : connections_forall_read(show_share, NULL);
213 :
214 0 : return 0;
215 : }
216 :
217 0 : if ((argc != 1) || !strequal(argv[0], "parseable")) {
218 0 : return net_status_usage(c, argc, argv);
219 : }
220 :
221 0 : return net_status_shares_parseable(c, argc, argv);
222 : }
223 :
224 0 : int net_status(struct net_context *c, int argc, const char **argv)
225 : {
226 0 : struct functable func[] = {
227 : {
228 : "sessions",
229 : net_status_sessions,
230 : NET_TRANSPORT_LOCAL,
231 : N_("Show list of open sessions"),
232 : N_("net status sessions [parseable]\n"
233 : " If parseable is specified, output is presented "
234 : "in a machine-parseable fashion.")
235 : },
236 : {
237 : "shares",
238 : net_status_shares,
239 : NET_TRANSPORT_LOCAL,
240 : N_("Show list of open shares"),
241 : N_("net status shares [parseable]\n"
242 : " If parseable is specified, output is presented "
243 : "in a machine-parseable fashion.")
244 : },
245 : {NULL, NULL, 0, NULL, NULL}
246 : };
247 0 : return net_run_function(c, argc, argv, "net status", func);
248 : }
|