1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 26 */ 27 28 #if defined(_KERNEL) || defined(_FAKE_KERNEL) 29 #include <sys/types.h> 30 #include <sys/sunddi.h> 31 #else 32 #include <string.h> 33 #endif 34 #include <smbsrv/string.h> 35 #include <smbsrv/netbios.h> 36 37 static int domainname_is_valid(char *domain_name); 38 39 /* 40 * Routines than support name compression. 41 * 42 * The NetBIOS name representation in all NetBIOS packets (for NAME, 43 * SESSION, and DATAGRAM services) is defined in the Domain Name 44 * Service RFC 883[3] as "compressed" name messages. This format is 45 * called "second-level encoding" in the section entitled 46 * "Representation of NetBIOS Names" in the Concepts and Methods 47 * document. 48 * 49 * For ease of description, the first two paragraphs from page 31, 50 * the section titled "Domain name representation and compression", 51 * of RFC 883 are replicated here: 52 * 53 * Domain names messages are expressed in terms of a sequence 54 * of labels. Each label is represented as a one octet length 55 * field followed by that number of octets. Since every domain 56 * name ends with the null label of the root, a compressed 57 * domain name is terminated by a length byte of zero. The 58 * high order two bits of the length field must be zero, and 59 * the remaining six bits of the length field limit the label 60 * to 63 octets or less. 61 * 62 * To simplify implementations, the total length of label 63 * octets and label length octets that make up a domain name is 64 * restricted to 255 octets or less. 65 * 66 * The following is the uncompressed representation of the NetBIOS name 67 * "FRED ", which is the 4 ASCII characters, F, R, E, D, followed by 12 68 * space characters (0x20). This name has the SCOPE_ID: "NETBIOS.COM" 69 * 70 * EGFCEFEECACACACACACACACACACACACA.NETBIOS.COM 71 * 72 * This uncompressed representation of names is called "first-level 73 * encoding" in the section entitled "Representation of NetBIOS Names" 74 * in the Concepts and Methods document. 75 * 76 * The following is a pictographic representation of the compressed 77 * representation of the previous uncompressed Domain Name 78 * representation. 79 * 80 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 81 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 82 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 83 * | 0x20 | E (0x45) | G (0x47) | F (0x46) | 84 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 85 * | C (0x43) | E (0x45) | F (0x46) | E (0x45) | 86 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 87 * | E (0x45) | C (0x43) | A (0x41) | C (0x43) | 88 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 89 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) | 90 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 91 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) | 92 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 93 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) | 94 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 95 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) | 96 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 97 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) | 98 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 99 * | A (0X41) | 0x07 | N (0x4E) | E (0x45) | 100 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 101 * | T (0x54) | B (0x42) | I (0x49) | O (0x4F) | 102 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 103 * | S (0x53) | 0x03 | C (0x43) | O (0x4F) | 104 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 105 * | M (0x4D) | 0x00 | 106 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 107 * 108 * Each section of a domain name is called a label [7 (page 31)]. A 109 * label can be a maximum of 63 bytes. The first byte of a label in 110 * compressed representation is the number of bytes in the label. For 111 * the above example, the first 0x20 is the number of bytes in the 112 * left-most label, EGFCEFEECACACACACACACACACACACACA, of the domain 113 * name. The bytes following the label length count are the characters 114 * of the label. The following labels are in sequence after the first 115 * label, which is the encoded NetBIOS name, until a zero (0x00) length 116 * count. The zero length count represents the root label, which is 117 * always null. 118 * 119 * A label length count is actually a 6-bit field in the label length 120 * field. The most significant 2 bits of the field, bits 7 and 6, are 121 * flags allowing an escape from the above compressed representation. 122 * If bits 7 and 6 are both set (11), the following 14 bits are an 123 * offset pointer into the full message to the actual label string from 124 * another domain name that belongs in this name. This label pointer 125 * allows for a further compression of a domain name in a packet. 126 * 127 * NetBIOS implementations can only use label string pointers in Name 128 * Service packets. They cannot be used in Session or Datagram Service 129 * packets. 130 * 131 * The other two possible values for bits 7 and 6 (01 and 10) of a label 132 * length field are reserved for future use by RFC 883[2 (page 32)]. 133 * 134 * Note that the first octet of a compressed name must contain one of 135 * the following bit patterns. (An "x" indicates a bit whose value may 136 * be either 0 or 1.): 137 * 138 * 00100000 - Netbios name, length must be 32 (decimal) 139 * 11xxxxxx - Label string pointer 140 * 10xxxxxx - Reserved 141 * 01xxxxxx - Reserved 142 */ 143 144 /* 145 * netbios_first_level_name_encode 146 * 147 * Put test description here. 148 * 149 * Inputs: 150 * char * in -> Name to encode 151 * char * out -> Buffer to encode into. 152 * int length -> # of bytes to encode. 153 * 154 * Returns: 155 * Nothing 156 */ 157 int 158 netbios_first_level_name_encode(unsigned char *name, unsigned char *scope, 159 unsigned char *out, int max_out) 160 { 161 unsigned char ch, len; 162 unsigned char *in; 163 unsigned char *lp; 164 unsigned char *op = out; 165 166 if (max_out < 0x21) 167 return (-1); 168 169 in = name; 170 *op++ = 0x20; 171 for (len = 0; len < NETBIOS_NAME_SZ; len++) { 172 ch = *in++; 173 *op++ = 'A' + ((ch >> 4) & 0xF); 174 *op++ = 'A' + ((ch) & 0xF); 175 } 176 177 max_out -= 0x21; 178 179 in = scope; 180 len = 0; 181 lp = op++; 182 while (((ch = *in++) != 0) && (max_out-- > 1)) { 183 if (ch == 0) { 184 if ((*lp = len) != 0) 185 *op++ = 0; 186 break; 187 } 188 if (ch == '.') { 189 *lp = len; 190 lp = op++; 191 len = 0; 192 } else { 193 *op++ = ch; 194 len++; 195 } 196 } 197 *lp = len; 198 if (len != 0) 199 *op = 0; 200 201 /*LINTED E_PTRDIFF_OVERFLOW*/ 202 return (op - out); 203 } 204 205 /* 206 * smb_first_level_name_decode 207 * 208 * The null terminated string "in" is the name to decode. The output 209 * is placed in the name_entry structure "name". 210 * 211 * The scope field is a series of length designated labels as described 212 * in the "Domain name representation and compression" section of RFC883. 213 * The two high order two bits of the length field must be zero, the 214 * remaining six bits contain the field length. The total length of the 215 * domain name is restricted to 255 octets but note that the trailing 216 * root label and its dot are not printed. When converting the labels, 217 * the length fields are replaced by dots. 218 * 219 * Returns the number of bytes scanned or -1 to indicate an error. 220 */ 221 int 222 netbios_first_level_name_decode(char *in, char *name, char *scope) 223 { 224 unsigned int length, bytes; 225 char c1, c2; 226 char *cp; 227 char *out; 228 229 cp = in; 230 231 if ((length = *cp++) != 0x20) { 232 return (-1); 233 } 234 235 out = name; 236 while (length > 0) { 237 c1 = *cp++; 238 c2 = *cp++; 239 240 if ('A' <= c1 && c1 <= 'P' && 'A' <= c2 && c2 <= 'P') { 241 c1 -= 'A'; 242 c2 -= 'A'; 243 *out++ = (c1 << 4) | (c2); 244 } else { 245 return (-1); /* conversion error */ 246 } 247 length -= 2; 248 } 249 250 out = scope; 251 bytes = 0; 252 for (length = *cp++; length != 0; length = *cp++) { 253 if ((length & 0xc0) != 0x00) { 254 /* 255 * This is a pointer or a reserved field. If it's 256 * a pointer (16-bits) we have to skip the next byte. 257 */ 258 if ((length & 0xc0) == 0xc0) { 259 cp++; 260 continue; 261 } 262 } 263 264 /* 265 * Replace the length with a '.', except for the first one. 266 */ 267 if (out != scope) { 268 *out++ = '.'; 269 bytes++; 270 } 271 272 while (length-- > 0) { 273 if (bytes++ >= (NETBIOS_DOMAIN_NAME_MAX - 1)) { 274 return (-1); 275 } 276 *out++ = *cp++; 277 } 278 } 279 *out = 0; 280 281 /* 282 * We are supposed to preserve all 8-bits of the domain name 283 * but due to the single byte representation in the name cache 284 * and UTF-8 encoding everywhere else, we restrict domain names 285 * to Appendix 1 - Domain Name Syntax Specification in RFC883. 286 */ 287 if (domainname_is_valid(scope)) { 288 (void) smb_strupr(scope); 289 /*LINTED E_PTRDIFF_OVERFLOW*/ 290 return (cp - in); 291 } 292 293 scope[0] = '\0'; 294 return (-1); 295 } 296 297 /* 298 * smb_netbios_name_isvalid 299 * 300 * This function is provided to be used by session service 301 * which runs in kernel in order to hide name_entry definition. 302 * 303 * It returns the decoded name in the provided buffer as 'out' 304 * if it's not null. 305 * 306 * Returns 0 if decode fails, 1 if it succeeds. 307 */ 308 int 309 netbios_name_isvalid(char *in, char *out) 310 { 311 char name[NETBIOS_NAME_SZ]; 312 char scope[NETBIOS_DOMAIN_NAME_MAX]; 313 314 if (netbios_first_level_name_decode(in, name, scope) < 0) 315 return (0); 316 317 if (out) 318 (void) strlcpy(out, name, NETBIOS_NAME_SZ); 319 320 return (1); 321 } 322 323 /* 324 * Characters that we allow in DNS domain names, in addition to 325 * alphanumeric characters. This is not quite consistent with 326 * RFC883. This is global so that it can be patched if there is 327 * a need to change the valid characters in the field. 328 */ 329 static const char dns_allowed[] = "-_"; 330 331 /* 332 * dns_is_allowed 333 * 334 * Check the dns_allowed characters and return true (1) if the character 335 * is in the table. Otherwise return false (0). 336 */ 337 static int 338 dns_is_allowed(unsigned char c) 339 { 340 const char *p = dns_allowed; 341 342 while (*p) { 343 if ((char)c == *p++) 344 return (1); 345 } 346 347 return (0); 348 } 349 350 351 /* 352 * domainname_is_valid 353 * 354 * Check the specified domain name for mostly compliance with RFC883 355 * Appendix 1. Names may contain alphanumeric characters, hyphens, 356 * underscores and dots. The first character after a dot must be an 357 * alphabetic character. RFC883 doesn't mention underscores but we 358 * allow it due to common use, and we don't check that labels end 359 * with an alphanumeric character. 360 * 361 * Returns true (1) if the name is valid. Otherwise returns false (0). 362 */ 363 static int 364 domainname_is_valid(char *domain_name) 365 { 366 char *name; 367 int first_char = 1; 368 369 if (domain_name == 0) 370 return (0); 371 372 for (name = domain_name; *name != 0; ++name) { 373 if (*name == '.') { 374 first_char = 1; 375 continue; 376 } 377 378 if (first_char) { 379 if (smb_isalpha_ascii(*name) == 0) 380 return (0); 381 382 first_char = 0; 383 continue; 384 } 385 386 if (smb_isalnum_ascii(*name) || dns_is_allowed(*name)) 387 continue; 388 389 return (0); 390 } 391 392 return (1); 393 } 394