s3: use TDB_INCOMPATIBLE_HASH (the jenkins hash) on all TDB_CLEAR_IF_FIRST tdb's.
[obnox/samba-ctdb.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                                           void *private_data)
92 {
93         struct sessionid session;
94
95         if ((rec->key.dptr[rec->key.dsize-1] != '\0')
96             || (rec->value.dsize != sizeof(struct sessionid))) {
97                 DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
98                 return 0;
99         }
100
101         memcpy(&session, rec->value.dptr, sizeof(session));
102
103         if (!serverid_exists(&session.pid)) {
104                 NTSTATUS status;
105
106                 DEBUG(10, ("Deleting sessionid.tdb record for pid %s\n",
107                            procid_str(talloc_tos(), &session.pid)));
108
109                 status = rec->delete_rec(rec);
110                 if (!NT_STATUS_IS_OK(status)) {
111                         DEBUG(1, ("Could not delete session.tdb record "
112                                   "for pid %s: %s\n",
113                                   procid_str(talloc_tos(), &session.pid),
114                                   nt_errstr(status)));
115                 }
116         }
117         return 0;
118 }
119
120 static int net_serverid_wipedbs(struct net_context *c, int argc,
121                                 const char **argv)
122 {
123         struct db_context *db;
124
125         connections_forall(net_serverid_wipedbs_conn, NULL);
126
127         db = db_open(NULL, lock_path("sessionid.tdb"), 0,
128                      TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDONLY, 0644);
129         if (db == NULL) {
130                 d_fprintf(stderr, "%s not initialised\n", lock_path("sessionid.tdb"));
131                 return -1;
132         }
133
134         db->traverse(db, net_serverid_wipedbs_sessionid, NULL);
135         TALLOC_FREE(db);
136         return 0;
137 }
138
139 int net_serverid(struct net_context *c, int argc, const char **argv)
140 {
141         struct functable func[] = {
142                 {
143                         "list",
144                         net_serverid_list,
145                         NET_TRANSPORT_LOCAL,
146                         N_("List all entries from serverid.tdb"),
147                         N_("net serverid list\n"
148                            "    List all entries from serverid.tdb")
149                 },
150                 {
151                         "wipe",
152                         net_serverid_wipe,
153                         NET_TRANSPORT_LOCAL,
154                         N_("Wipe the serverid.tdb for the current node"),
155                         N_("net serverid wipe\n"
156                            "    Wipe the serverid.tdb for the current node")
157                 },
158                 {
159                         "wipedbs",
160                         net_serverid_wipedbs,
161                         NET_TRANSPORT_LOCAL,
162                         N_("Clean dead entries from connections.tdb and "
163                            "sessionid.tdb"),
164                         N_("net serverid wipedbs\n"
165                            "    Clean dead entries from connections.tdb and "
166                            "sessionid.tdb")
167                 },
168                 {NULL, NULL, 0, NULL, NULL}
169         };
170
171         return net_run_function(c, argc, argv, "net serverid", func);
172 }