00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 extern struct in_addr allones_ip;
00027
00028 extern uint16 samba_nb_type;
00029
00030 static void become_domain_master_browser_bcast(const char *);
00031
00032
00033
00034
00035
00036 static void become_domain_master_fail(struct subnet_record *subrec,
00037 struct response_record *rrec,
00038 struct nmb_name *fail_name)
00039 {
00040 unstring failname;
00041 struct work_record *work;
00042 struct server_record *servrec;
00043
00044 pull_ascii_nstring(failname, sizeof(failname), fail_name->name);
00045 work = find_workgroup_on_subnet(subrec, failname);
00046 if(!work) {
00047 DEBUG(0,("become_domain_master_fail: Error - cannot find \
00048 workgroup %s on subnet %s\n", failname, subrec->subnet_name));
00049 return;
00050 }
00051
00052
00053 work->dom_state = DOMAIN_NONE;
00054
00055 if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
00056 DEBUG(0,("become_domain_master_fail: Error - cannot find server %s \
00057 in workgroup %s on subnet %s\n",
00058 global_myname(), work->work_group, subrec->subnet_name));
00059 return;
00060 }
00061
00062
00063 servrec->serv.type &= ~SV_TYPE_DOMAIN_MASTER;
00064
00065
00066 subrec->work_changed = True;
00067
00068 DEBUG(0,("become_domain_master_fail: Failed to become a domain master browser for \
00069 workgroup %s on subnet %s. Couldn't register name %s.\n",
00070 work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
00071 }
00072
00073
00074
00075
00076
00077 static void become_domain_master_stage2(struct subnet_record *subrec,
00078 struct userdata_struct *userdata,
00079 struct nmb_name *registered_name,
00080 uint16 nb_flags,
00081 int ttl, struct in_addr registered_ip)
00082 {
00083 unstring regname;
00084 struct work_record *work;
00085 struct server_record *servrec;
00086
00087 pull_ascii_nstring(regname, sizeof(regname), registered_name->name);
00088 work = find_workgroup_on_subnet( subrec, regname);
00089
00090 if(!work) {
00091 DEBUG(0,("become_domain_master_stage2: Error - cannot find \
00092 workgroup %s on subnet %s\n", regname, subrec->subnet_name));
00093 return;
00094 }
00095
00096 if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
00097 DEBUG(0,("become_domain_master_stage2: Error - cannot find server %s \
00098 in workgroup %s on subnet %s\n",
00099 global_myname(), regname, subrec->subnet_name));
00100 work->dom_state = DOMAIN_NONE;
00101 return;
00102 }
00103
00104
00105 work->dom_state = DOMAIN_MST;
00106
00107
00108 servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER);
00109
00110
00111 subrec->work_changed = True;
00112
00113 if( DEBUGLVL( 0 ) ) {
00114 dbgtext( "*****\n\nSamba server %s ", global_myname() );
00115 dbgtext( "is now a domain master browser for " );
00116 dbgtext( "workgroup %s ", work->work_group );
00117 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
00118 }
00119
00120 if( subrec == unicast_subnet ) {
00121 struct nmb_name nmbname;
00122 struct in_addr my_first_ip;
00123 struct in_addr *nip;
00124
00125
00126
00127
00128
00129
00130 make_nmb_name(&nmbname, global_myname(), 0x20);
00131
00132 work->dmb_name = nmbname;
00133
00134 nip = iface_n_ip(0);
00135
00136 if (!nip) {
00137 DEBUG(0,("become_domain_master_stage2: Error. iface_n_ip returned NULL\n"));
00138 return;
00139 }
00140
00141 my_first_ip = *nip;
00142
00143 putip((char *)&work->dmb_addr, &my_first_ip);
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 become_domain_master_browser_bcast(work->work_group);
00160 } else {
00161
00162
00163
00164
00165
00166
00167 insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176 static void become_domain_master_stage1(struct subnet_record *subrec, const char *wg_name)
00177 {
00178 struct work_record *work;
00179
00180 DEBUG(2,("become_domain_master_stage1: Becoming domain master browser for \
00181 workgroup %s on subnet %s\n", wg_name, subrec->subnet_name));
00182
00183
00184 if((work = find_workgroup_on_subnet( subrec, wg_name )) == NULL) {
00185 DEBUG(0,("become_domain_master_stage1: Error - unable to find workgroup %s on subnet %s.\n",
00186 wg_name, subrec->subnet_name));
00187 return;
00188 }
00189
00190 DEBUG(3,("become_domain_master_stage1: go to first stage: register <1b> name\n"));
00191 work->dom_state = DOMAIN_WAIT;
00192
00193
00194 register_name(subrec, work->work_group,0x1b,samba_nb_type,
00195 become_domain_master_stage2,
00196 become_domain_master_fail, NULL);
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 static void become_domain_master_query_success(struct subnet_record *subrec,
00207 struct userdata_struct *userdata,
00208 struct nmb_name *nmbname, struct in_addr ip,
00209 struct res_rec *rrec)
00210 {
00211 unstring name;
00212 pull_ascii_nstring(name, sizeof(name), nmbname->name);
00213
00214
00215
00216
00217
00218
00219
00220
00221 if(ismyip(ip) || ip_equal(allones_ip, ip) || is_zero_ip(ip)) {
00222 if( DEBUGLVL( 3 ) ) {
00223 dbgtext( "become_domain_master_query_success():\n" );
00224 dbgtext( "Our address (%s) ", inet_ntoa(ip) );
00225 dbgtext( "returned in query for name %s ", nmb_namestr(nmbname) );
00226 dbgtext( "(domain master browser name) " );
00227 dbgtext( "on subnet %s.\n", subrec->subnet_name );
00228 dbgtext( "Continuing with domain master code.\n" );
00229 }
00230
00231 become_domain_master_stage1(subrec, name);
00232 } else {
00233 if( DEBUGLVL( 0 ) ) {
00234 dbgtext( "become_domain_master_query_success:\n" );
00235 dbgtext( "There is already a domain master browser at " );
00236 dbgtext( "IP %s for workgroup %s ", inet_ntoa(ip), name );
00237 dbgtext( "registered on subnet %s.\n", subrec->subnet_name );
00238 }
00239 }
00240 }
00241
00242
00243
00244
00245
00246
00247
00248 static void become_domain_master_query_fail(struct subnet_record *subrec,
00249 struct response_record *rrec,
00250 struct nmb_name *question_name, int fail_code)
00251 {
00252 unstring name;
00253
00254
00255
00256
00257 if((subrec == unicast_subnet) && (fail_code != NAM_ERR)) {
00258 DEBUG(0,("become_domain_master_query_fail: Error %d returned when \
00259 querying WINS server for name %s.\n",
00260 fail_code, nmb_namestr(question_name)));
00261 return;
00262 }
00263
00264
00265 pull_ascii_nstring(name, sizeof(name), question_name->name);
00266 become_domain_master_stage1(subrec, name);
00267 }
00268
00269
00270
00271
00272
00273 static void become_domain_master_browser_bcast(const char *workgroup_name)
00274 {
00275 struct subnet_record *subrec;
00276
00277 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
00278 struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
00279
00280 if (work && (work->dom_state == DOMAIN_NONE)) {
00281 struct nmb_name nmbname;
00282 make_nmb_name(&nmbname,workgroup_name,0x1b);
00283
00284
00285
00286
00287
00288
00289 if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL) {
00290 if( DEBUGLVL( 0 ) ) {
00291 dbgtext( "become_domain_master_browser_bcast:\n" );
00292 dbgtext( "Attempting to become domain master browser on " );
00293 dbgtext( "workgroup %s on subnet %s\n",
00294 workgroup_name, subrec->subnet_name );
00295 }
00296
00297
00298
00299
00300
00301
00302 DEBUG(0,("become_domain_master_browser_bcast: querying subnet %s \
00303 for domain master browser on workgroup %s\n", subrec->subnet_name, workgroup_name));
00304
00305 query_name(subrec, workgroup_name, nmbname.name_type,
00306 become_domain_master_query_success,
00307 become_domain_master_query_fail,
00308 NULL);
00309 }
00310 }
00311 }
00312 }
00313
00314
00315
00316
00317
00318 static void become_domain_master_browser_wins(const char *workgroup_name)
00319 {
00320 struct work_record *work;
00321
00322 work = find_workgroup_on_subnet(unicast_subnet, workgroup_name);
00323
00324 if (work && (work->dom_state == DOMAIN_NONE)) {
00325 struct nmb_name nmbname;
00326
00327 make_nmb_name(&nmbname,workgroup_name,0x1b);
00328
00329
00330
00331
00332
00333
00334 if (find_name_on_subnet(unicast_subnet, &nmbname, FIND_SELF_NAME) == NULL) {
00335 if( DEBUGLVL( 0 ) ) {
00336 dbgtext( "become_domain_master_browser_wins:\n" );
00337 dbgtext( "Attempting to become domain master browser " );
00338 dbgtext( "on workgroup %s, subnet %s.\n",
00339 workgroup_name, unicast_subnet->subnet_name );
00340 }
00341
00342
00343
00344
00345
00346
00347 DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
00348 for domain master browser name %s on workgroup %s\n",
00349 inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
00350
00351 query_name(unicast_subnet, workgroup_name, nmbname.name_type,
00352 become_domain_master_query_success,
00353 become_domain_master_query_fail,
00354 NULL);
00355 }
00356 }
00357 }
00358
00359
00360
00361
00362
00363
00364 void add_domain_names(time_t t)
00365 {
00366 static time_t lastrun = 0;
00367
00368 if ((lastrun != 0) && (t < lastrun + (CHECK_TIME_ADD_DOM_NAMES * 60)))
00369 return;
00370
00371 lastrun = t;
00372
00373
00374 if (lp_domain_logons())
00375 add_logon_names();
00376
00377
00378 if(lp_domain_master()) {
00379 if(we_are_a_wins_client()) {
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 become_domain_master_browser_wins(lp_workgroup());
00390 } else {
00391 become_domain_master_browser_bcast(lp_workgroup());
00392 }
00393 }
00394 }