root/source3/nmbd/nmbd_processlogon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. delay_logon
  2. delayed_init_logon_handler
  3. process_logon_packet

   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
   7    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
   8    
   9    This program is free software; you can redistribute it and/or modify
  10    it under the terms of the GNU General Public License as published by
  11    the Free Software Foundation; either version 3 of the License, or
  12    (at your option) any later version.
  13    
  14    This program is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17    GNU General Public License for more details.
  18    
  19    You should have received a copy of the GNU General Public License
  20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21    
  22    Revision History:
  23 
  24 */
  25 
  26 #include "includes.h"
  27 
  28 struct sam_database_info {
  29         uint32 index;
  30         uint32 serial_lo, serial_hi;
  31         uint32 date_lo, date_hi;
  32 };
  33 
  34 /**
  35  * check whether the client belongs to the hosts
  36  * for which initial logon should be delayed...
  37  */
  38 static bool delay_logon(const char *peer_name, const char *peer_addr)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40         const char **delay_list = lp_init_logon_delayed_hosts();
  41         const char *peer[2];
  42 
  43         if (delay_list == NULL) {
  44                 return False;
  45         }
  46 
  47         peer[0] = peer_name;
  48         peer[1] = peer_addr;
  49 
  50         return list_match(delay_list, (const char *)peer, client_match);
  51 }
  52 
  53 static void delayed_init_logon_handler(struct event_context *event_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  54                                        struct timed_event *te,
  55                                        struct timeval now,
  56                                        void *private_data)
  57 {
  58         struct packet_struct *p = (struct packet_struct *)private_data;
  59 
  60         DEBUG(10, ("delayed_init_logon_handler (%lx): re-queuing packet.\n",
  61                    (unsigned long)te));
  62 
  63         queue_packet(p);
  64 
  65         TALLOC_FREE(te);
  66 }
  67 
  68 /****************************************************************************
  69 Process a domain logon packet
  70 **************************************************************************/
  71 
  72 void process_logon_packet(struct packet_struct *p, char *buf,int len, 
     /* [<][>][^][v][top][bottom][index][help] */
  73                           const char *mailslot)
  74 {
  75         struct dgram_packet *dgram = &p->packet.dgram;
  76         fstring my_name;
  77         fstring reply_name;
  78         char outbuf[1024];
  79         int code;
  80         uint16 token = 0;
  81         uint32 ntversion = 0;
  82         uint16 lmnttoken = 0;
  83         uint16 lm20token = 0;
  84         uint32 domainsidsize;
  85         bool short_request = False;
  86         char *getdc;
  87         char *uniuser; /* Unicode user name. */
  88         fstring ascuser;
  89         char *unicomp; /* Unicode computer name. */
  90         size_t size;
  91         struct sockaddr_storage ss;
  92         const struct sockaddr_storage *pss;
  93         struct in_addr ip;
  94 
  95         in_addr_to_sockaddr_storage(&ss, p->ip);
  96         pss = iface_ip((struct sockaddr *)&ss);
  97         if (!pss) {
  98                 DEBUG(5,("process_logon_packet:can't find outgoing interface "
  99                         "for packet from IP %s\n",
 100                         inet_ntoa(p->ip) ));
 101                 return;
 102         }
 103         ip = ((struct sockaddr_in *)pss)->sin_addr;
 104 
 105         memset(outbuf, 0, sizeof(outbuf));
 106 
 107         if (!lp_domain_logons()) {
 108                 DEBUG(5,("process_logon_packet: Logon packet received from IP %s and domain \
 109 logons are not enabled.\n", inet_ntoa(p->ip) ));
 110                 return;
 111         }
 112 
 113         fstrcpy(my_name, global_myname());
 114 
 115         code = get_safe_SVAL(buf,len,buf,0,-1);
 116         DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
 117 
 118         switch (code) {
 119                 case 0:
 120                         {
 121                                 fstring mach_str, user_str, getdc_str;
 122                                 char *q = buf + 2;
 123                                 char *machine = q;
 124                                 char *user = skip_string(buf,len,machine);
 125 
 126                                 if (!user || PTR_DIFF(user, buf) >= len) {
 127                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 128                                         return;
 129                                 }
 130                                 getdc = skip_string(buf,len,user);
 131 
 132                                 if (!getdc || PTR_DIFF(getdc, buf) >= len) {
 133                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 134                                         return;
 135                                 }
 136                                 q = skip_string(buf,len,getdc);
 137 
 138                                 if (!q || PTR_DIFF(q + 5, buf) > len) {
 139                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 140                                         return;
 141                                 }
 142                                 token = SVAL(q,3);
 143 
 144                                 fstrcpy(reply_name,my_name);
 145 
 146                                 pull_ascii_fstring(mach_str, machine);
 147                                 pull_ascii_fstring(user_str, user);
 148                                 pull_ascii_fstring(getdc_str, getdc);
 149 
 150                                 DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
 151                                         mach_str,inet_ntoa(p->ip),user_str,token));
 152 
 153                                 q = outbuf;
 154                                 SSVAL(q, 0, 6);
 155                                 q += 2;
 156 
 157                                 fstrcpy(reply_name, "\\\\");
 158                                 fstrcat(reply_name, my_name);
 159                                 size = push_ascii(q,reply_name,
 160                                                 sizeof(outbuf)-PTR_DIFF(q, outbuf),
 161                                                 STR_TERMINATE);
 162                                 if (size == (size_t)-1) {
 163                                         return;
 164                                 }
 165                                 q = skip_string(outbuf,sizeof(outbuf),q); /* PDC name */
 166 
 167                                 SSVAL(q, 0, token);
 168                                 q += 2;
 169 
 170                                 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf));
 171 
 172                                 send_mailslot(True, getdc_str,
 173                                                 outbuf,PTR_DIFF(q,outbuf),
 174                                                 global_myname(), 0x0,
 175                                                 mach_str,
 176                                                 dgram->source_name.name_type,
 177                                                 p->ip, ip, p->port);
 178                                 break;
 179                         }
 180 
 181                 case LOGON_PRIMARY_QUERY:
 182                         {
 183                                 fstring mach_str, getdc_str;
 184                                 fstring source_name;
 185                                 char *q = buf + 2;
 186                                 char *machine = q;
 187 
 188                                 if (!lp_domain_master()) {
 189                                         /* We're not Primary Domain Controller -- ignore this */
 190                                         return;
 191                                 }
 192 
 193                                 getdc = skip_string(buf,len,machine);
 194 
 195                                 if (!getdc || PTR_DIFF(getdc, buf) >= len) {
 196                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 197                                         return;
 198                                 }
 199                                 q = skip_string(buf,len,getdc);
 200 
 201                                 if (!q || PTR_DIFF(q, buf) >= len) {
 202                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 203                                         return;
 204                                 }
 205                                 q = ALIGN2(q, buf);
 206 
 207                                 /* At this point we can work out if this is a W9X or NT style
 208                                    request. Experiments show that the difference is wether the
 209                                    packet ends here. For a W9X request we now end with a pair of
 210                                    bytes (usually 0xFE 0xFF) whereas with NT we have two further
 211                                    strings - the following is a simple way of detecting this */
 212 
 213                                 if (len - PTR_DIFF(q, buf) <= 3) {
 214                                         short_request = True;
 215                                 } else {
 216                                         unicomp = q;
 217 
 218                                         if (PTR_DIFF(q, buf) >= len) {
 219                                                 DEBUG(0,("process_logon_packet: bad packet\n"));
 220                                                 return;
 221                                         }
 222 
 223                                         /* A full length (NT style) request */
 224                                         q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
 225 
 226                                         if (PTR_DIFF(q, buf) >= len) {
 227                                                 DEBUG(0,("process_logon_packet: bad packet\n"));
 228                                                 return;
 229                                         }
 230 
 231                                         if (len - PTR_DIFF(q, buf) > 8) {
 232                                                 /* with NT5 clients we can sometimes
 233                                                         get additional data - a length specificed string
 234                                                         containing the domain name, then 16 bytes of
 235                                                         data (no idea what it is) */
 236                                                 int dom_len = CVAL(q, 0);
 237                                                 q++;
 238                                                 if (dom_len != 0) {
 239                                                         q += dom_len + 1;
 240                                                 }
 241                                                 q += 16;
 242                                         }
 243 
 244                                         if (PTR_DIFF(q + 8, buf) > len) {
 245                                                 DEBUG(0,("process_logon_packet: bad packet\n"));
 246                                                 return;
 247                                         }
 248 
 249                                         ntversion = IVAL(q, 0);
 250                                         lmnttoken = SVAL(q, 4);
 251                                         lm20token = SVAL(q, 6);
 252                                 }
 253 
 254                                 /* Construct reply. */
 255                                 q = outbuf;
 256                                 SSVAL(q, 0, NETLOGON_RESPONSE_FROM_PDC);
 257                                 q += 2;
 258 
 259                                 fstrcpy(reply_name,my_name);
 260                                 size = push_ascii(q, reply_name,
 261                                                 sizeof(outbuf)-PTR_DIFF(q, outbuf),
 262                                                 STR_TERMINATE);
 263                                 if (size == (size_t)-1) {
 264                                         return;
 265                                 }
 266                                 q = skip_string(outbuf,sizeof(outbuf),q); /* PDC name */
 267 
 268                                 /* PDC and domain name */
 269                                 if (!short_request) {
 270                                         /* Make a full reply */
 271                                         q = ALIGN2(q, outbuf);
 272 
 273                                         q += dos_PutUniCode(q, my_name,
 274                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
 275                                                 True); /* PDC name */
 276                                         q += dos_PutUniCode(q, lp_workgroup(),
 277                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
 278                                                 True); /* Domain name*/
 279                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) {
 280                                                 return;
 281                                         }
 282                                         SIVAL(q, 0, 1); /* our nt version */
 283                                         SSVAL(q, 4, 0xffff); /* our lmnttoken */
 284                                         SSVAL(q, 6, 0xffff); /* our lm20token */
 285                                         q += 8;
 286                                 }
 287 
 288                                 /* RJS, 21-Feb-2000, we send a short reply if the request was short */
 289 
 290                                 pull_ascii_fstring(mach_str, machine);
 291 
 292                                 DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, \
 293 reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
 294                                         mach_str,inet_ntoa(p->ip), reply_name, lp_workgroup(),
 295                                         NETLOGON_RESPONSE_FROM_PDC, (uint32)ntversion, (uint32)lmnttoken,
 296                                         (uint32)lm20token ));
 297 
 298                                 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf));
 299 
 300                                 pull_ascii_fstring(getdc_str, getdc);
 301                                 pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
 302 
 303                                 send_mailslot(True, getdc_str,
 304                                         outbuf,PTR_DIFF(q,outbuf),
 305                                         global_myname(), 0x0,
 306                                         source_name,
 307                                         dgram->source_name.name_type,
 308                                         p->ip, ip, p->port);
 309                                 return;
 310                         }
 311 
 312                 case LOGON_SAM_LOGON_REQUEST:
 313 
 314                         {
 315                                 fstring getdc_str;
 316                                 fstring source_name;
 317                                 char *source_addr;
 318                                 char *q = buf + 2;
 319                                 fstring asccomp;
 320 
 321                                 q += 2;
 322 
 323                                 if (PTR_DIFF(q, buf) >= len) {
 324                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 325                                         return;
 326                                 }
 327 
 328                                 unicomp = q;
 329                                 uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
 330 
 331                                 if (PTR_DIFF(uniuser, buf) >= len) {
 332                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 333                                         return;
 334                                 }
 335 
 336                                 getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
 337 
 338                                 if (PTR_DIFF(getdc, buf) >= len) {
 339                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 340                                         return;
 341                                 }
 342 
 343                                 q = skip_string(buf,len,getdc);
 344 
 345                                 if (!q || PTR_DIFF(q + 8, buf) >= len) {
 346                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 347                                         return;
 348                                 }
 349 
 350                                 q += 4; /* Account Control Bits - indicating username type */
 351                                 domainsidsize = IVAL(q, 0);
 352                                 q += 4;
 353 
 354                                 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST sidsize %d, len = %d\n", domainsidsize, len));
 355 
 356                                 if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) {
 357                                         q += domainsidsize;
 358                                         q = ALIGN4(q, buf);
 359                                 }
 360 
 361                                 DEBUG(5,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) ));
 362 
 363                                 if (len - PTR_DIFF(q, buf) > 8) {
 364                                         /* with NT5 clients we can sometimes
 365                                                 get additional data - a length specificed string
 366                                                 containing the domain name, then 16 bytes of
 367                                                 data (no idea what it is) */
 368                                         int dom_len = CVAL(q, 0);
 369                                         q++;
 370                                         if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) {
 371                                                 q += dom_len + 1;
 372                                         }
 373                                         q += 16;
 374                                 }
 375 
 376                                 if (PTR_DIFF(q + 8, buf) > len) {
 377                                         DEBUG(0,("process_logon_packet: bad packet\n"));
 378                                         return;
 379                                 }
 380 
 381                                 ntversion = IVAL(q, 0);
 382                                 lmnttoken = SVAL(q, 4);
 383                                 lm20token = SVAL(q, 6);
 384                                 q += 8;
 385 
 386                                 DEBUG(3,("process_logon_packet: LOGON_SAM_LOGON_REQUEST sidsize %d ntv %d\n", domainsidsize, ntversion));
 387 
 388                                 /*
 389                                  * we respond regadless of whether the machine is in our password 
 390                                  * database. If it isn't then we let smbd send an appropriate error.
 391                                  * Let's ignore the SID.
 392                                  */
 393                                 pull_ucs2_fstring(ascuser, uniuser);
 394                                 pull_ucs2_fstring(asccomp, unicomp);
 395                                 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST user %s\n", ascuser));
 396 
 397                                 fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */
 398                                 fstrcat(reply_name, my_name);
 399 
 400                                 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
 401                                         asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(),
 402                                 LOGON_SAM_LOGON_RESPONSE ,lmnttoken));
 403 
 404                                 /* Construct reply. */
 405 
 406                                 q = outbuf;
 407                                 /* we want the simple version unless we are an ADS PDC..which means  */
 408                                 /* never, at least for now */
 409                                 if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
 410                                         if (SVAL(uniuser, 0) == 0) {
 411                                                 SSVAL(q, 0, LOGON_SAM_LOGON_USER_UNKNOWN);      /* user unknown */
 412                                         } else {
 413                                                 SSVAL(q, 0, LOGON_SAM_LOGON_RESPONSE);
 414                                         }
 415 
 416                                         q += 2;
 417 
 418                                         q += dos_PutUniCode(q, reply_name,
 419                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
 420                                                 True);
 421                                         q += dos_PutUniCode(q, ascuser,
 422                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
 423                                                 True);
 424                                         q += dos_PutUniCode(q, lp_workgroup(),
 425                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
 426                                                 True);
 427                                 }
 428 #ifdef HAVE_ADS
 429                                 else {
 430                                         struct GUID domain_guid;
 431                                         UUID_FLAT flat_guid;
 432                                         char *domain;
 433                                         char *hostname;
 434                                         char *component, *dc, *q1;
 435                                         char *q_orig = q;
 436                                         int str_offset;
 437                                         char *saveptr = NULL;
 438 
 439                                         domain = get_mydnsdomname(talloc_tos());
 440                                         if (!domain) {
 441                                                 DEBUG(2,
 442                                                 ("get_mydnsdomname failed.\n"));
 443                                                 return;
 444                                         }
 445                                         hostname = get_myname(talloc_tos());
 446                                         if (!hostname) {
 447                                                 DEBUG(2,
 448                                                 ("get_myname failed.\n"));
 449                                                 return;
 450                                         }
 451 
 452                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) {
 453                                                 return;
 454                                         }
 455                                         if (SVAL(uniuser, 0) == 0) {
 456                                                 SIVAL(q, 0, LOGON_SAM_LOGON_USER_UNKNOWN_EX);   /* user unknown */
 457                                         } else {
 458                                                 SIVAL(q, 0, LOGON_SAM_LOGON_RESPONSE_EX);
 459                                         }
 460                                         q += 4;
 461 
 462                                         SIVAL(q, 0, NBT_SERVER_PDC|NBT_SERVER_GC|NBT_SERVER_LDAP|NBT_SERVER_DS|
 463                                                 NBT_SERVER_KDC|NBT_SERVER_TIMESERV|NBT_SERVER_CLOSEST|NBT_SERVER_WRITABLE);
 464                                         q += 4;
 465 
 466                                         /* Push Domain GUID */
 467                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < UUID_FLAT_SIZE) {
 468                                                 return;
 469                                         }
 470                                         if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
 471                                                 DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
 472                                                 return;
 473                                         }
 474 
 475                                         smb_uuid_pack(domain_guid, &flat_guid);
 476                                         memcpy(q, &flat_guid.info, UUID_FLAT_SIZE);
 477                                         q += UUID_FLAT_SIZE;
 478 
 479                                         /* Forest */
 480                                         str_offset = q - q_orig;
 481                                         dc = domain;
 482                                         q1 = q;
 483                                         while ((component = strtok_r(dc, ".", &saveptr)) != NULL) {
 484                                                 dc = NULL;
 485                                                 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 1) {
 486                                                         return;
 487                                                 }
 488                                                 size = push_ascii(&q[1], component,
 489                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
 490                                                         0);
 491                                                 if (size == (size_t)-1 || size > 0xff) {
 492                                                         return;
 493                                                 }
 494                                                 SCVAL(q, 0, size);
 495                                                 q += (size + 1);
 496                                         }
 497 
 498                                         /* Unk0 */
 499                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 4) {
 500                                                 return;
 501                                         }
 502                                         SCVAL(q, 0, 0);
 503                                         q++;
 504 
 505                                         /* Domain */
 506                                         SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
 507                                         SCVAL(q, 1, str_offset & 0xFF);
 508                                         q += 2;
 509 
 510                                         /* Hostname */
 511                                         size = push_ascii(&q[1], hostname,
 512                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
 513                                                         0);
 514                                         if (size == (size_t)-1 || size > 0xff) {
 515                                                 return;
 516                                         }
 517                                         SCVAL(q, 0, size);
 518                                         q += (size + 1);
 519 
 520                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 3) {
 521                                                 return;
 522                                         }
 523 
 524                                         SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
 525                                         SCVAL(q, 1, str_offset & 0xFF);
 526                                         q += 2;
 527 
 528                                         /* NETBIOS of domain */
 529                                         size = push_ascii(&q[1], lp_workgroup(),
 530                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
 531                                                         STR_UPPER);
 532                                         if (size == (size_t)-1 || size > 0xff) {
 533                                                 return;
 534                                         }
 535                                         SCVAL(q, 0, size);
 536                                         q += (size + 1);
 537 
 538                                         /* Unk1 */
 539                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 2) {
 540                                                 return;
 541                                         }
 542 
 543                                         SCVAL(q, 0, 0);
 544                                         q++;
 545 
 546                                         /* NETBIOS of hostname */
 547                                         size = push_ascii(&q[1], my_name,
 548                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
 549                                                         0);
 550                                         if (size == (size_t)-1 || size > 0xff) {
 551                                                 return;
 552                                         }
 553                                         SCVAL(q, 0, size);
 554                                         q += (size + 1);
 555 
 556                                         /* Unk2 */
 557                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 4) {
 558                                                 return;
 559                                         }
 560 
 561                                         SCVAL(q, 0, 0);
 562                                         q++;
 563 
 564                                         /* User name */
 565                                         if (SVAL(uniuser, 0) != 0) {
 566                                                 size = push_ascii(&q[1], ascuser,
 567                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
 568                                                         0);
 569                                                 if (size == (size_t)-1 || size > 0xff) {
 570                                                         return;
 571                                                 }
 572                                                 SCVAL(q, 0, size);
 573                                                 q += (size + 1);
 574                                         }
 575 
 576                                         q_orig = q;
 577                                         /* Site name */
 578                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 1) {
 579                                                 return;
 580                                         }
 581                                         size = push_ascii(&q[1], "Default-First-Site-Name",
 582                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
 583                                                         0);
 584                                         if (size == (size_t)-1 || size > 0xff) {
 585                                                 return;
 586                                         }
 587                                         SCVAL(q, 0, size);
 588                                         q += (size + 1);
 589 
 590                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 18) {
 591                                                 return;
 592                                         }
 593 
 594                                         /* Site name (2) */
 595                                         str_offset = q - q_orig;
 596                                         SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
 597                                         SCVAL(q, 1, str_offset & 0xFF);
 598                                         q += 2;
 599 
 600                                         SCVAL(q, 0, PTR_DIFF(q,q1));
 601                                         SCVAL(q, 1, 0x10); /* unknown */
 602 
 603                                         SIVAL(q, 0, 0x00000002);
 604                                         q += 4; /* unknown */
 605                                         SIVAL(q, 0, ntohl(ip.s_addr));
 606                                         q += 4;
 607                                         SIVAL(q, 0, 0x00000000);
 608                                         q += 4; /* unknown */
 609                                         SIVAL(q, 0, 0x00000000);
 610                                         q += 4; /* unknown */
 611                                 }
 612 #endif
 613 
 614                                 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) {
 615                                         return;
 616                                 }
 617 
 618                                 /* tell the client what version we are */
 619                                 SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13); 
 620                                 /* our ntversion */
 621                                 SSVAL(q, 4, 0xffff); /* our lmnttoken */
 622                                 SSVAL(q, 6, 0xffff); /* our lm20token */
 623                                 q += 8;
 624 
 625                                 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf));
 626 
 627                                 pull_ascii_fstring(getdc_str, getdc);
 628                                 pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
 629                                 source_addr = SMB_STRDUP(inet_ntoa(dgram->header.source_ip));
 630                                 if (source_addr == NULL) {
 631                                         DEBUG(3, ("out of memory copying client"
 632                                                   " address string\n"));
 633                                         return;
 634                                 }
 635 
 636                                 /*
 637                                  * handle delay.
 638                                  * packets requeued after delay are marked as
 639                                  * locked.
 640                                  */
 641                                 if ((p->locked == False) &&
 642                                     (strlen(ascuser) == 0) &&
 643                                     delay_logon(source_name, source_addr))
 644                                 {
 645                                         struct timeval when;
 646 
 647                                         DEBUG(3, ("process_logon_packet: "
 648                                                   "delaying initial logon "
 649                                                   "reply for client %s(%s) for "
 650                                                   "%u milliseconds\n",
 651                                                   source_name, source_addr,
 652                                                   lp_init_logon_delay()));
 653 
 654                                         when = timeval_current_ofs(0,
 655                                                 lp_init_logon_delay() * 1000);
 656                                         p->locked = true;
 657                                         event_add_timed(nmbd_event_context(),
 658                                                         NULL,
 659                                                         when,
 660                                                         delayed_init_logon_handler,
 661                                                         p);
 662                                 } else {
 663                                         DEBUG(3, ("process_logon_packet: "
 664                                                   "processing delayed initial "
 665                                                   "logon reply for client "
 666                                                   "%s(%s)\n",
 667                                                   source_name, source_addr));
 668 
 669                                         p->locked = false;
 670                                         send_mailslot(true, getdc,
 671                                                 outbuf,PTR_DIFF(q,outbuf),
 672                                                 global_myname(), 0x0,
 673                                                 source_name,
 674                                                 dgram->source_name.name_type,
 675                                                 p->ip, ip, p->port);
 676                                 }
 677 
 678                                 SAFE_FREE(source_addr);
 679 
 680                                 break;
 681                         }
 682 
 683                 /* Announce change to UAS or SAM.  Send by the domain controller when a
 684                 replication event is required. */
 685 
 686                 case NETLOGON_ANNOUNCE_UAS:
 687                         DEBUG(5, ("Got NETLOGON_ANNOUNCE_UAS\n"));
 688                         break;
 689 
 690                 default:
 691                         DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
 692                         return;
 693         }
 694 }

/* [<][>][^][v][top][bottom][index][help] */