diff options
Diffstat (limited to 'source/nmbd/nmbd_processlogon.c')
-rw-r--r-- | source/nmbd/nmbd_processlogon.c | 235 |
1 files changed, 24 insertions, 211 deletions
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c index b65cebe2035..c9130fe478c 100644 --- a/source/nmbd/nmbd_processlogon.c +++ b/source/nmbd/nmbd_processlogon.c @@ -1,11 +1,10 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 1.9. NBT netbios routines and daemon - version 2 Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Luke Kenneth Casson Leighton 1994-1998 Copyright (C) Jeremy Allison 1994-1998 - Copyright (C) Jim McDonough 2002 - Copyright (C) Anthony Liguori 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,37 +29,6 @@ extern pstring global_myname; extern fstring global_myworkgroup; -struct sam_database_info { - uint32 index; - uint32 serial_lo, serial_hi; - uint32 date_lo, date_hi; -}; - -/**************************************************************************** -Send a message to smbd to do a sam delta sync -**************************************************************************/ -static void send_repl_message(uint32 low_serial) -{ - TDB_CONTEXT *tdb; - - tdb = tdb_open_log(lock_path("connections.tdb"), 0, - TDB_DEFAULT, O_RDONLY, 0); - - if (!tdb) { - DEBUG(3, ("send_repl_message(): failed to open connections " - "database\n")); - return; - } - - DEBUG(3, ("sending replication message, serial = 0x%04x\n", - low_serial)); - - message_send_all(tdb, MSG_SMB_SAM_REPL, &low_serial, - sizeof(low_serial), False, NULL); - - tdb_close(tdb); -} - /**************************************************************************** Process a domain logon packet **************************************************************************/ @@ -84,13 +52,14 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len, pstring ascuser; char *unicomp; /* Unicode computer name. */ + START_PROFILE(domain_logon); memset(outbuf, 0, sizeof(outbuf)); if (!lp_domain_logons()) { DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \ logons are not enabled.\n", inet_ntoa(p->ip) )); - return; + goto done; } pstrcpy(my_name, global_myname); @@ -146,7 +115,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); if (!lp_domain_master()) { /* We're not Primary Domain Controller -- ignore this */ - return; + goto done; } getdc = skip_string(machine,1); @@ -199,6 +168,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */ q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True); /* Domain name*/ + SIVAL(q, 0, 1); /* our nt version */ SSVAL(q, 4, 0xffff); /* our lmnttoken */ SSVAL(q, 6, 0xffff); /* our lm20token */ @@ -221,13 +191,12 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", dgram->source_name.name, dgram->source_name.name_type, p->ip, *iface_ip(p->ip), p->port); - return; + goto done; } case SAMLOGON: { char *q = buf + 2; - fstring asccomp; q += 2; unicomp = q; @@ -272,123 +241,33 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", * database. If it isn't then we let smbd send an appropriate error. * Let's ignore the SID. */ - pull_ucs2_pstring(ascuser, uniuser); - pull_ucs2_fstring(asccomp, unicomp); + + pstrcpy(ascuser, dos_unistr(uniuser)); DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser)); fstrcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */ fstrcpy(reply_name+2,my_name); DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n", - asccomp,inet_ntoa(p->ip), ascuser, reply_name, global_myworkgroup, + dos_unistr(unicomp),inet_ntoa(p->ip), ascuser, reply_name, global_myworkgroup, SAMLOGON_R ,lmnttoken)); /* Construct reply. */ q = outbuf; - /* we want the simple version unless we are an ADS PDC..which means */ - /* never, at least for now */ - if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) { - if (SVAL(uniuser, 0) == 0) { - SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */ - } else { - SSVAL(q, 0, SAMLOGON_R); - } - - q += 2; - - q += dos_PutUniCode(q, reply_name,sizeof(pstring), True); - q += dos_PutUniCode(q, ascuser, sizeof(pstring), True); - q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True); - } -#ifdef HAVE_ADS - else { - GUID domain_guid; - pstring domain; - char *component, *dc, *q1; - uint8 size; - - safe_strcpy(domain, lp_realm(), sizeof(domain)); - - if (SVAL(uniuser, 0) == 0) { - SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */ - } else { - SSVAL(q, 0, SAMLOGON_AD_R); - } - q += 2; - - SSVAL(q, 0, 0); - q += 2; - SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS| - ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE); - q += 4; - - /* Push Domain GUID */ - if (False == secrets_fetch_domain_guid(domain, &domain_guid)) { - DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain)); - return; - } - memcpy(q, &domain_guid, sizeof(domain_guid)); - q += sizeof(domain_guid); - - /* Push domain components */ - dc = domain; - q1 = q; - while ((component = strtok(dc, "."))) { - dc = NULL; - size = push_ascii(&q[1], component, -1, 0); - SCVAL(q, 0, size); - q += (size + 1); - } - SCVAL(q, 0, 0); q++; - SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */ - q += 2; /* it must follow the domain name. */ - - /* Push dns host name */ - size = push_ascii(&q[1], global_myname, -1, 0); - SCVAL(q, 0, size); - q += (size + 1); - SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */ - q += 2; /* it must follow the domain name. */ - - /* Push NETBIOS of domain */ - size = push_ascii(&q[1], domain, -1, STR_UPPER); - SCVAL(q, 0, size); - q += (size + 1); - SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */ - /* null terminator would not be needed because size is included */ - - /* Push NETBIOS of hostname */ - size = push_ascii(&q[1], my_name, -1, 0); - SCVAL(q, 0, size); - q += (size + 1); - SCVAL(q, 0, 0); q++; /* null terminator or empty field? */ - - /* Push user account */ - size = push_ascii(&q[1], ascuser, -1, 0); - SCVAL(q, 0, size); - q += (size + 1); - - /* Push 'Default-First-Site-Name' */ - size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0); - SCVAL(q, 0, size); - q += (size + 1); - - SSVAL(q, 0, 0xc000); /* unknown */ - SCVAL(q, 2, PTR_DIFF(q,q1)); - SCVAL(q, 3, 0x10); /* unknown */ - q += 4; - - SIVAL(q, 0, 0x00000002); q += 4; /* unknown */ - SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4; - SIVAL(q, 0, 0x00000000); q += 4; /* unknown */ - SIVAL(q, 0, 0x00000000); q += 4; /* unknown */ - } -#endif + if (SVAL(uniuser, 0) == 0) { + SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */ + } else { + SSVAL(q, 0, SAMLOGON_R); + } + q += 2; + + q += dos_PutUniCode(q, reply_name,sizeof(pstring), True); + q += dos_PutUniCode(q, ascuser, sizeof(pstring), True); + q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True); /* tell the client what version we are */ - SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13); - /* our ntversion */ + SIVAL(q, 0, 1); /* our ntversion */ SSVAL(q, 4, 0xffff); /* our lmnttoken */ SSVAL(q, 6, 0xffff); /* our lm20token */ q += 8; @@ -404,78 +283,12 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", break; } - /* Announce change to UAS or SAM. Send by the domain controller when a - replication event is required. */ - - case SAM_UAS_CHANGE: { - struct sam_database_info *db_info; - char *q = buf + 2; - int i, db_count; - uint32 low_serial; - - /* Header */ - - low_serial = IVAL(q, 0); q += 4; /* Low serial number */ - - q += 4; /* Date/time */ - q += 4; /* Pulse */ - q += 4; /* Random */ - - /* Domain info */ - - q = skip_string(q, 1); /* PDC name */ - q = skip_string(q, 1); /* Domain name */ - q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode PDC name */ - q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode domain name */ - - /* Database info */ - - db_count = SVAL(q, 0); q += 2; - - db_info = (struct sam_database_info *) - malloc(sizeof(struct sam_database_info) * db_count); - - if (db_info == NULL) { - DEBUG(3, ("out of memory allocating info for %d databases\n", - db_count)); - return; - } - - for (i = 0; i < db_count; i++) { - db_info[i].index = IVAL(q, 0); - db_info[i].serial_lo = IVAL(q, 4); - db_info[i].serial_hi = IVAL(q, 8); - db_info[i].date_lo = IVAL(q, 12); - db_info[i].date_hi = IVAL(q, 16); - q += 20; - } - - /* Domain SID */ - - q += IVAL(q, 0) + 4; /* 4 byte length plus data */ - - q += 2; /* Alignment? */ - - /* Misc other info */ - - q += 4; /* NT version (0x1) */ - q += 2; /* LMNT token (0xff) */ - q += 2; /* LM20 token (0xff) */ - - SAFE_FREE(db_info); /* Not sure whether we need to do anything - useful with these */ - - /* Send message to smbd */ - - send_repl_message(low_serial); - - break; - } - default: { DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code)); - return; + goto done; } } +done: + END_PROFILE(domain_logon); } |