2
Unix SMB/CIFS implementation.
4
Copyright (C) Andrew Tridgell 1997-1998
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.
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.
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/>.
21
#include "web/swat_proto.h"
23
#define _(x) lang_msg_rotate(talloc_tos(),x)
25
#define PIDMAP struct PidMap
27
/* how long to wait for start/stops to take effect */
36
static PIDMAP *pidmap;
37
static int PID_or_Machine; /* 0 = show PID, else show Machine name */
39
static struct server_id smbd_pid;
41
/* from 2nd call on, remove old list */
42
static void initPid2Machine (void)
44
/* show machine name rather PID on table "Open Files"? */
48
for (p = pidmap; p != NULL; p = next) {
50
DLIST_REMOVE(pidmap, p);
51
SAFE_FREE(p->machine);
59
/* add new PID <-> Machine name mapping */
60
static void addPid2Machine (struct server_id pid, const char *machine)
62
/* show machine name rather PID on table "Open Files"? */
66
if ((newmap = SMB_MALLOC_P(PIDMAP)) == NULL) {
67
/* XXX need error message for this?
68
if malloc fails, PID is always shown */
73
newmap->machine = SMB_STRDUP(machine);
75
DLIST_ADD(pidmap, newmap);
79
/* lookup PID <-> Machine name mapping */
80
static char *mapPid2Machine (struct server_id pid)
82
static char pidbuf [64];
85
/* show machine name rather PID on table "Open Files"? */
87
for (map = pidmap; map != NULL; map = map->next) {
88
if (procid_equal(&pid, &map->pid)) {
89
if (map->machine == NULL) /* no machine name */
97
/* PID not in list or machine name NULL? return pid as string */
98
snprintf (pidbuf, sizeof (pidbuf) - 1, "%s",
99
procid_str_static(&pid));
103
static const char *tstring(TALLOC_CTX *ctx, time_t t)
106
buf = talloc_strdup(ctx, time_to_asc(t));
110
buf = talloc_all_string_sub(ctx,
120
static void print_share_mode(const struct share_mode_entry *e,
121
const char *sharepath,
127
size_t converted_size;
129
if (!is_valid_share_mode_entry(e)) {
133
deny_mode = map_share_mode_to_deny_mode(e->share_access,
136
printf("<tr><td>%s</td>",_(mapPid2Machine(e->pid)));
137
printf("<td>%u</td>",(unsigned int)e->uid);
139
switch ((deny_mode>>4)&0xF) {
140
case DENY_NONE: printf("DENY_NONE"); break;
141
case DENY_ALL: printf("DENY_ALL "); break;
142
case DENY_DOS: printf("DENY_DOS "); break;
143
case DENY_FCB: printf("DENY_FCB "); break;
144
case DENY_READ: printf("DENY_READ "); break;
145
case DENY_WRITE:printf("DENY_WRITE "); break;
150
if (e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA)) {
151
printf("%s", _("RDWR "));
152
} else if (e->access_mask & FILE_WRITE_DATA) {
153
printf("%s", _("WRONLY "));
155
printf("%s", _("RDONLY "));
161
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
162
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
163
printf("EXCLUSIVE+BATCH ");
164
else if (e->op_type & EXCLUSIVE_OPLOCK)
165
printf("EXCLUSIVE ");
166
else if (e->op_type & BATCH_OPLOCK)
168
else if (e->op_type & LEVEL_II_OPLOCK)
174
push_utf8_allocate(&utf8_fname, fname, &converted_size);
175
printf("<td>%s</td><td>%s</td></tr>\n",
176
utf8_fname,tstring(talloc_tos(),e->time.tv_sec));
177
SAFE_FREE(utf8_fname);
181
/* kill off any connections chosen by the user */
182
static int traverse_fn1(struct db_record *rec,
183
const struct connections_key *key,
184
const struct connections_data *crec,
187
if (crec->cnum == -1 && process_exists(crec->pid)) {
189
slprintf(buf,sizeof(buf)-1,"kill_%s", procid_str_static(&crec->pid));
190
if (cgi_variable(buf)) {
198
/* traversal fn for showing machine connections */
199
static int traverse_fn2(struct db_record *rec,
200
const struct connections_key *key,
201
const struct connections_data *crec,
204
if (crec->cnum == -1 || !process_exists(crec->pid) ||
205
procid_equal(&crec->pid, &smbd_pid))
208
addPid2Machine (crec->pid, crec->machine);
210
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td>\n",
211
procid_str_static(&crec->pid),
212
crec->machine, crec->addr,
213
tstring(talloc_tos(),crec->start));
214
if (geteuid() == 0) {
215
printf("<td><input type=submit value=\"X\" name=\"kill_%s\"></td>\n",
216
procid_str_static(&crec->pid));
223
/* traversal fn for showing share connections */
224
static int traverse_fn3(struct db_record *rec,
225
const struct connections_key *key,
226
const struct connections_data *crec,
229
if (crec->cnum == -1 || !process_exists(crec->pid))
232
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",
233
crec->servicename, uidtoname(crec->uid),
234
gidtoname(crec->gid),procid_str_static(&crec->pid),
236
tstring(talloc_tos(),crec->start));
241
/* show the current server status */
242
void status_page(void)
246
int refresh_interval=30;
249
TALLOC_CTX *ctx = talloc_stackframe();
251
smbd_pid = pid_to_procid(pidfile_pid("smbd"));
253
if (cgi_variable("smbd_restart") || cgi_variable("all_restart")) {
259
if (cgi_variable("smbd_start") || cgi_variable("all_start")) {
264
if (cgi_variable("smbd_stop") || cgi_variable("all_stop")) {
269
if (cgi_variable("nmbd_restart") || cgi_variable("all_restart")) {
274
if (cgi_variable("nmbd_start") || cgi_variable("all_start")) {
279
if (cgi_variable("nmbd_stop")|| cgi_variable("all_stop")) {
285
if (cgi_variable("winbindd_restart") || cgi_variable("all_restart")) {
291
if (cgi_variable("winbindd_start") || cgi_variable("all_start")) {
296
if (cgi_variable("winbindd_stop") || cgi_variable("all_stop")) {
301
/* wait for daemons to start/stop */
305
if (cgi_variable("autorefresh")) {
307
} else if (cgi_variable("norefresh")) {
309
} else if (cgi_variable("refresh")) {
313
if ((v=cgi_variable("refresh_interval"))) {
314
refresh_interval = atoi(v);
317
if (cgi_variable("show_client_in_col_1")) {
321
if (cgi_variable("show_pid_in_col_1")) {
325
connections_forall(traverse_fn1, NULL);
329
printf("<H2>%s</H2>\n", _("Server Status"));
331
printf("<FORM method=post>\n");
334
printf("<input type=submit value=\"%s\" name=\"autorefresh\">\n", _("Auto Refresh"));
335
printf("<br>%s", _("Refresh Interval: "));
336
printf("<input type=text size=2 name=\"refresh_interval\" value=\"%d\">\n",
339
printf("<input type=submit value=\"%s\" name=\"norefresh\">\n", _("Stop Refreshing"));
340
printf("<br>%s%d\n", _("Refresh Interval: "), refresh_interval);
341
printf("<input type=hidden name=\"refresh\" value=\"1\">\n");
348
printf("<tr><td>%s</td><td>%s</td></tr>", _("version:"), samba_version_string());
351
printf("<tr><td>%s</td><td>%s</td>\n", _("smbd:"), smbd_running()?_("running"):_("not running"));
352
if (geteuid() == 0) {
353
if (smbd_running()) {
355
printf("<td><input type=submit name=\"smbd_stop\" value=\"%s\"></td>\n", _("Stop smbd"));
357
printf("<td><input type=submit name=\"smbd_start\" value=\"%s\"></td>\n", _("Start smbd"));
359
printf("<td><input type=submit name=\"smbd_restart\" value=\"%s\"></td>\n", _("Restart smbd"));
364
printf("<tr><td>%s</td><td>%s</td>\n", _("nmbd:"), nmbd_running()?_("running"):_("not running"));
365
if (geteuid() == 0) {
366
if (nmbd_running()) {
368
printf("<td><input type=submit name=\"nmbd_stop\" value=\"%s\"></td>\n", _("Stop nmbd"));
370
printf("<td><input type=submit name=\"nmbd_start\" value=\"%s\"></td>\n", _("Start nmbd"));
372
printf("<td><input type=submit name=\"nmbd_restart\" value=\"%s\"></td>\n", _("Restart nmbd"));
378
printf("<tr><td>%s</td><td>%s</td>\n", _("winbindd:"), winbindd_running()?_("running"):_("not running"));
379
if (geteuid() == 0) {
380
if (winbindd_running()) {
382
printf("<td><input type=submit name=\"winbindd_stop\" value=\"%s\"></td>\n", _("Stop winbindd"));
384
printf("<td><input type=submit name=\"winbindd_start\" value=\"%s\"></td>\n", _("Start winbindd"));
386
printf("<td><input type=submit name=\"winbindd_restart\" value=\"%s\"></td>\n", _("Restart winbindd"));
391
if (geteuid() == 0) {
392
printf("<tr><td></td><td></td>\n");
393
if (nr_running >= 1) {
394
/* stop, restart all */
395
printf("<td><input type=submit name=\"all_stop\" value=\"%s\"></td>\n", _("Stop All"));
396
printf("<td><input type=submit name=\"all_restart\" value=\"%s\"></td>\n", _("Restart All"));
398
else if (nr_running == 0) {
400
printf("<td><input type=submit name=\"all_start\" value=\"%s\"></td>\n", _("Start All"));
404
printf("</table>\n");
407
printf("<p><h3>%s</h3>\n", _("Active Connections"));
408
printf("<table border=1>\n");
409
printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th>\n", _("PID"), _("Client"), _("IP address"), _("Date"));
410
if (geteuid() == 0) {
411
printf("<th>%s</th>\n", _("Kill"));
415
connections_forall(traverse_fn2, NULL);
417
printf("</table><p>\n");
419
printf("<p><h3>%s</h3>\n", _("Active Shares"));
420
printf("<table border=1>\n");
421
printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n\n",
422
_("Share"), _("User"), _("Group"), _("PID"), _("Client"), _("Date"));
424
connections_forall(traverse_fn3, NULL);
426
printf("</table><p>\n");
428
printf("<h3>%s</h3>\n", _("Open Files"));
429
printf("<table border=1>\n");
430
printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n",
431
_("PID"), _("UID"), _("Sharing"), _("R/W"), _("Oplock"), _("File"), _("Date"));
433
locking_init_readonly();
434
share_mode_forall(print_share_mode, NULL);
436
printf("</table>\n");
438
printf("<br><input type=submit name=\"show_client_in_col_1\" value=\"%s\">\n", _("Show Client in col 1"));
439
printf("<input type=submit name=\"show_pid_in_col_1\" value=\"%s\">\n", _("Show PID in col 1"));
444
/* this little JavaScript allows for automatic refresh
445
of the page. There are other methods but this seems
446
to be the best alternative */
447
printf("<script language=\"JavaScript\">\n");
448
printf("<!--\nsetTimeout('window.location.replace(\"%s/status?refresh_interval=%d&refresh=1\")', %d)\n",
451
refresh_interval*1000);
452
printf("//-->\n</script>\n");