s3: Fix a long-standing problem with recycled PIDs
[sfrench/samba-autobuild/.git] / source3 / utils / net_serverid.c
1 /*
2    Samba Unix/Linux SMB client library
3    net serverid commands
4    Copyright (C) Volker Lendecke 2010
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
20 #include "includes.h"
21 #include "utils/net.h"
22
23 static int net_serverid_list_fn(const struct server_id *id,
24                                 uint32_t msg_flags, void *priv)
25 {
26         char *str = procid_str(talloc_tos(), id);
27         d_printf("%s %llu 0x%x\n", str, (unsigned long long)id->unique_id,
28                  (unsigned int)msg_flags);
29         TALLOC_FREE(str);
30         return 0;
31 }
32
33 static int net_serverid_list(struct net_context *c, int argc,
34                              const char **argv)
35 {
36         d_printf("pid unique_id msg_flags\n");
37         return serverid_traverse_read(net_serverid_list_fn, NULL) ? 0 : -1;
38 }
39
40 static int net_serverid_wipe_fn(struct db_record *rec,
41                                 const struct server_id *id,
42                                 uint32_t msg_flags, void *private_data)
43 {
44         NTSTATUS status;
45
46 #ifdef CLUSTER_SUPPORT
47         if (id->vnn != get_my_vnn()) {
48                 return 0;
49         }
50 #endif
51         status = rec->delete_rec(rec);
52         if (!NT_STATUS_IS_OK(status)) {
53                 char *str = procid_str(talloc_tos(), id);
54                 DEBUG(1, ("Could not delete serverid.tdb record %s: %s\n",
55                           str, nt_errstr(status)));
56                 TALLOC_FREE(str);
57         }
58         return 0;
59 }
60
61 static int net_serverid_wipe(struct net_context *c, int argc,
62                              const char **argv)
63 {
64         return serverid_traverse(net_serverid_wipe_fn, NULL) ? 0 : -1;
65 }
66
67 static int net_serverid_wipedbs_conn(
68         struct db_record *rec,
69         const struct connections_key *key,
70         const struct connections_data *data,
71         void *private_data)
72 {
73         if (!serverid_exists(&key->pid)) {
74                 NTSTATUS status;
75
76                 DEBUG(10, ("Deleting connections.tdb record for pid %s\n",
77                            procid_str(talloc_tos(), &key->pid)));
78
79                 status = rec->delete_rec(rec);
80                 if (!NT_STATUS_IS_OK(status)) {
81                         DEBUG(1, ("Could not delete connections.tdb record "
82                                   "for pid %s: %s\n",
83                                   procid_str(talloc_tos(), &key->pid),
84                                   nt_errstr(status)));
85                 }
86         }
87         return 0;
88 }
89
90 static int net_serverid_wipedbs_sessionid(struct db_record *rec,
91                                           const char *key,
92                                           struct sessionid *session,
93                                           void *private_data)
94 {
95         if (!serverid_exists(&session->pid)) {
96                 NTSTATUS status;
97
98                 DEBUG(10, ("Deleting sessionid.tdb record for pid %s\n",
99                            procid_str(talloc_tos(), &session->pid)));
100
101                 status = rec->delete_rec(rec);
102                 if (!NT_STATUS_IS_OK(status)) {
103                         DEBUG(1, ("Could not delete session.tdb record "
104                                   "for pid %s: %s\n",
105                                   procid_str(talloc_tos(), &session->pid),
106                                   nt_errstr(status)));
107                 }
108         }
109         return 0;
110 }
111
112 static int net_serverid_wipedbs(struct net_context *c, int argc,
113                                 const char **argv)
114 {
115         connections_forall(net_serverid_wipedbs_conn, NULL);
116         sessionid_traverse(net_serverid_wipedbs_sessionid, NULL);
117         return 0;
118 }
119
120 int net_serverid(struct net_context *c, int argc, const char **argv)
121 {
122         struct functable func[] = {
123                 {
124                         "list",
125                         net_serverid_list,
126                         NET_TRANSPORT_LOCAL,
127                         N_("List all entries from serverid.tdb"),
128                         N_("net serverid list\n"
129                            "    List all entries from serverid.tdb")
130                 },
131                 {
132                         "wipe",
133                         net_serverid_wipe,
134                         NET_TRANSPORT_LOCAL,
135                         N_("Wipe the serverid.tdb for the current node"),
136                         N_("net serverid wipe\n"
137                            "    Wipe the serverid.tdb for the current node")
138                 },
139                 {
140                         "wipedbs",
141                         net_serverid_wipedbs,
142                         NET_TRANSPORT_LOCAL,
143                         N_("Clean dead entries from connections.tdb and "
144                            "sessionid.tdb"),
145                         N_("net serverid wipedbs\n"
146                            "    Clean dead entries from connections.tdb and "
147                            "sessionid.tdb")
148                 },
149                 {NULL, NULL, 0, NULL, NULL}
150         };
151
152         return net_run_function(c, argc, argv, "net serverid", func);
153 }