s4:dsdb:tests: Also pass tests if asserted identity is present
[Samba.git] / source3 / nmbd / nmbd_mynames.c
blobb95c2e2f17df68b89df027df3fae75fca4b0f19d
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6 Copyright (C) Jeremy Allison 1994-2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "nmbd/nmbd.h"
26 extern uint16_t samba_nb_type; /* Samba's NetBIOS type. */
28 static const char **mynames = NULL;
30 static bool add_unique_netbios_name(const char *name)
32 size_t i, num_names = talloc_array_length(mynames);
33 char *str = NULL;
34 const char **tmp = NULL;
36 for (i=0; i<num_names; i++) {
37 if (strequal(name, mynames[i])) {
38 return true;
42 str = talloc_strdup(NULL, name);
43 if (str == NULL) {
44 return false;
47 tmp = talloc_realloc(NULL, mynames, const char *, num_names+1);
48 if (tmp == NULL) {
49 TALLOC_FREE(str);
50 return false;
52 tmp[num_names] = talloc_move(tmp, &str);
53 mynames = tmp;
54 return true;
57 bool nmbd_init_my_netbios_names(void)
59 const char *name = lp_netbios_name();
60 const char **aliases = lp_netbios_aliases();
62 TALLOC_FREE(mynames);
64 if (name[0] != '\0') {
65 bool ok = add_unique_netbios_name(name);
66 if (!ok) {
67 return false;
71 if (aliases == NULL) {
72 return true;
75 while (*aliases != NULL) {
76 bool ok = add_unique_netbios_name(*aliases);
77 if (!ok) {
78 return false;
80 aliases += 1;
83 return true;
86 const char *my_netbios_names(int i)
88 size_t num_names = talloc_array_length(mynames);
90 if ((i >= 0) && (i < num_names)) {
91 return mynames[i];
94 return NULL;
97 /****************************************************************************
98 Fail funtion when registering my netbios names.
99 **************************************************************************/
101 static void my_name_register_failed(struct subnet_record *subrec,
102 struct response_record *rrec, struct nmb_name *nmbname)
104 DEBUG(0,("my_name_register_failed: Failed to register my name %s on subnet %s.\n",
105 nmb_namestr(nmbname), subrec->subnet_name));
109 /****************************************************************************
110 Add my workgroup and my given names to one subnet
111 Also add the magic Samba names.
112 **************************************************************************/
114 void register_my_workgroup_one_subnet(struct subnet_record *subrec)
116 int i;
118 struct work_record *work;
120 /* Create the workgroup on the subnet. */
121 if((work = create_workgroup_on_subnet(subrec, lp_workgroup(),
122 PERMANENT_TTL)) == NULL) {
123 DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
124 Exiting.\n", lp_workgroup(), subrec->subnet_name));
125 return;
128 /* Each subnet entry, except for the wins_server_subnet has
129 the magic Samba names. */
130 add_samba_names_to_subnet(subrec);
132 /* Register all our names including aliases. */
133 for (i=0; my_netbios_names(i); i++) {
134 register_name(subrec, my_netbios_names(i),0x20,samba_nb_type,
135 NULL,
136 my_name_register_failed, NULL);
137 register_name(subrec, my_netbios_names(i),0x03,samba_nb_type,
138 NULL,
139 my_name_register_failed, NULL);
140 register_name(subrec, my_netbios_names(i),0x00,samba_nb_type,
141 NULL,
142 my_name_register_failed, NULL);
145 /* Initiate election processing, register the workgroup names etc. */
146 initiate_myworkgroup_startup(subrec, work);
149 /*******************************************************************
150 Utility function to add a name to the unicast subnet, or add in
151 our IP address if it already exists.
152 ******************************************************************/
154 static void insert_refresh_name_into_unicast( struct subnet_record *subrec,
155 struct nmb_name *nmbname, uint16_t nb_type )
157 struct name_record *namerec;
159 if (!we_are_a_wins_client()) {
160 insert_permanent_name_into_unicast(subrec, nmbname, nb_type);
161 return;
164 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) {
165 unstring name;
166 pull_ascii_nstring(name, sizeof(name), nmbname->name);
167 /* The name needs to be created on the unicast subnet. */
168 (void)add_name_to_subnet( unicast_subnet, name,
169 nmbname->name_type, nb_type,
170 MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
171 } else {
172 /* The name already exists on the unicast subnet. Add our local
173 IP for the given broadcast subnet to the name. */
174 add_ip_to_name_record( namerec, subrec->myip);
178 /****************************************************************************
179 Add my workgroup and my given names to the subnet lists.
180 Also add the magic Samba names.
181 **************************************************************************/
183 bool register_my_workgroup_and_names(void)
185 struct subnet_record *subrec;
186 int i;
187 const char **cluster_addresses = NULL;
189 for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
190 register_my_workgroup_one_subnet(subrec);
193 /* We still need to add the magic Samba
194 names and the netbios names to the unicast subnet directly. This is
195 to allow unicast node status requests and queries to still work
196 in a broadcast only environment. */
198 add_samba_names_to_subnet(unicast_subnet);
200 for (i=0; my_netbios_names(i); i++) {
201 for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
203 * Ensure all the IP addresses are added if we are multihomed.
205 struct nmb_name nmbname;
207 make_nmb_name(&nmbname, my_netbios_names(i),0x20);
208 insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
210 make_nmb_name(&nmbname, my_netbios_names(i),0x3);
211 insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
213 make_nmb_name(&nmbname, my_netbios_names(i),0x0);
214 insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
219 * add in any cluster addresses. We need to response to these,
220 * but not listen on them. This allows us to run nmbd on every
221 * node in the cluster, and have all of them register with a
222 * WINS server correctly
224 if (lp_clustering()) {
225 cluster_addresses = lp_cluster_addresses();
227 if (cluster_addresses) {
228 int a, n;
229 unsigned name_types[] = {0x20, 0x3, 0x0};
231 for (i=0; my_netbios_names(i); i++) {
232 for(subrec = FIRST_SUBNET; subrec; subrec = subrec->next) {
233 for (n=0;n<ARRAY_SIZE(name_types);n++) {
234 struct name_record *namerec;
235 struct nmb_name nmbname;
236 struct in_addr ip;
237 make_nmb_name(&nmbname, my_netbios_names(i), name_types[n]);
238 namerec = find_name_on_subnet(unicast_subnet, &nmbname, FIND_SELF_NAME);
239 if (namerec == NULL) continue;
240 for (a=0;cluster_addresses[a];a++) {
241 ip = interpret_addr2(cluster_addresses[a]);
242 add_ip_to_name_record(namerec, ip);
250 * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
251 * also for the same reasons.
254 for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
256 * Ensure all the IP addresses are added if we are multihomed.
258 struct nmb_name nmbname;
260 make_nmb_name(&nmbname, lp_workgroup(), 0x0);
261 insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
263 make_nmb_name(&nmbname, lp_workgroup(), 0x1e);
264 insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
268 * We need to add the Samba names to the remote broadcast subnet,
269 * as NT 4.x does directed broadcast requests to the *<0x0> name.
272 add_samba_names_to_subnet(remote_broadcast_subnet);
274 return True;
277 /****************************************************************************
278 Remove all the names we registered.
279 **************************************************************************/
281 void release_wins_names(void)
283 struct subnet_record *subrec = unicast_subnet;
284 struct name_record *namerec, *nextnamerec;
286 for (namerec = subrec->namelist; namerec; namerec = nextnamerec) {
287 nextnamerec = namerec->next;
288 if( (namerec->data.source == SELF_NAME)
289 && !NAME_IS_DEREGISTERING(namerec) )
290 release_name( subrec, namerec, standard_success_release,
291 NULL, NULL);
295 /*******************************************************************
296 Refresh our registered names with WINS
297 ******************************************************************/
299 void refresh_my_names(time_t t)
301 struct name_record *namerec;
303 if (wins_srv_count() < 1)
304 return;
306 for (namerec = unicast_subnet->namelist; namerec; namerec = namerec->next) {
307 /* Each SELF name has an individual time to be refreshed. */
308 if ((namerec->data.source == SELF_NAME) &&
309 (namerec->data.refresh_time < t) &&
310 (namerec->data.death_time != PERMANENT_TTL)) {
311 /* We cheat here and pretend the refresh is going to be
312 successful & update the refresh times. This stops
313 multiple refresh calls being done. We actually
314 deal with refresh failure in the fail_fn.
316 if (!is_refresh_already_queued(unicast_subnet, namerec)) {
317 wins_refresh_name(namerec);
319 namerec->data.death_time = t + lp_max_ttl();
320 namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);