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 /* 38 * Routines than support name compression. 39 * 40 * The NetBIOS name representation in all NetBIOS packets (for NAME, 41 * SESSION, and DATAGRAM services) is defined in the Domain Name 42 * Service RFC 883[3] as "compressed" name messages. This format is 43 * called "second-level encoding" in the section entitled 44 * "Representation of NetBIOS Names" in the Concepts and Methods 45 * document. 46 * 47 * For ease of description, the first two paragraphs from page 31, 48 * the section titled "Domain name representation and compression", 49 * of RFC 883 are replicated here: 50 * 51 * Domain names messages are expressed in terms of a sequence 52 * of labels. Each label is represented as a one octet length 53 * field followed by that number of octets. Since every domain 54 * name ends with the null label of the root, a compressed 55 * domain name is terminated by a length byte of zero. The 56 * high order two bits of the length field must be zero, and 57 * the remaining six bits of the length field limit the label 58 * to 63 octets or less. 59 * 60 * To simplify implementations, the total length of label 61 * octets and label length octets that make up a domain name is 62 * restricted to 255 octets or less. 63 * 64 * The following is the uncompressed representation of the NetBIOS name 65 * "FRED ", which is the 4 ASCII characters, F, R, E, D, followed by 12 66 * space characters (0x20). This name has the SCOPE_ID: "NETBIOS.COM" 67 * 68 * EGFCEFEECACACACACACACACACACACACA.NETBIOS.COM 69 * 70 * This uncompressed representation of names is called "first-level 71 * encoding" in the section entitled "Representation of NetBIOS Names" 72 * in the Concepts and Methods document. 73 * 74 * The following is a pictographic representation of the compressed 75 * representation of the previous uncompressed Domain Name 76 * representation. 77 * 78 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 79 * 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 80 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 81 * | 0x20 | E (0x45) | G (0x47) | F (0x46) | 82 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 83 * | C (0x43) | E (0x45) | F (0x46) | E (0x45) | 84 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 85 * | E (0x45) | C (0x43) | A (0x41) | C (0x43) | 86 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 87 * | A (0x41) | 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) | 0x07 | N (0x4E) | E (0x45) | 98 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 99 * | T (0x54) | B (0x42) | I (0x49) | O (0x4F) | 100 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 101 * | S (0x53) | 0x03 | C (0x43) | O (0x4F) | 102 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 103 * | M (0x4D) | 0x00 | 104 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 105 * 106 * Each section of a domain name is called a label [7 (page 31)]. A 107 * label can be a maximum of 63 bytes. The first byte of a label in 108 * compressed representation is the number of bytes in the label. For 109 * the above example, the first 0x20 is the number of bytes in the 110 * left-most label, EGFCEFEECACACACACACACACACACACACA, of the domain 111 * name. The bytes following the label length count are the characters 112 * of the label. The following labels are in sequence after the first 113 * label, which is the encoded NetBIOS name, until a zero (0x00) length 114 * count. The zero length count represents the root label, which is 115 * always null. 116 * 117 * A label length count is actually a 6-bit field in the label length 118 * field. The most significant 2 bits of the field, bits 7 and 6, are 119 * flags allowing an escape from the above compressed representation. 120 * If bits 7 and 6 are both set (11), the following 14 bits are an 121 * offset pointer into the full message to the actual label string from 122 * another domain name that belongs in this name. This label pointer 123 * allows for a further compression of a domain name in a packet. 124 * 125 * NetBIOS implementations can only use label string pointers in Name 126 * Service packets. They cannot be used in Session or Datagram Service 127 * packets. 128 * 129 * The other two possible values for bits 7 and 6 (01 and 10) of a label 130 * length field are reserved for future use by RFC 883[2 (page 32)]. 131 * 132 * Note that the first octet of a compressed name must contain one of 133 * the following bit patterns. (An "x" indicates a bit whose value may 134 * be either 0 or 1.): 135 * 136 * 00100000 - Netbios name, length must be 32 (decimal) 137 * 11xxxxxx - Label string pointer 138 * 10xxxxxx - Reserved 139 * 01xxxxxx - Reserved 140 */ 141 142 /* 143 * netbios_first_level_name_encode 144 * 145 * Put test description here. 146 * 147 * Inputs: 148 * char * in -> Name to encode 149 * char * out -> Buffer to encode into. 150 * int length -> # of bytes to encode. 151 * 152 * Returns: 153 * Nothing 154 */ 155 int 156 netbios_first_level_name_encode(unsigned char *name, unsigned char *scope, 157 unsigned char *out, int max_out) 158 { 159 unsigned char ch, len; 160 unsigned char *in; 161 unsigned char *lp; 162 unsigned char *op = out; 163 164 if (max_out < 0x21) 165 return (-1); 166 167 in = name; 168 *op++ = 0x20; 169 for (len = 0; len < NETBIOS_NAME_SZ; len++) { 170 ch = *in++; 171 *op++ = 'A' + ((ch >> 4) & 0xF); 172 *op++ = 'A' + ((ch) & 0xF); 173 } 174 175 max_out -= 0x21; 176 177 in = scope; 178 len = 0; 179 lp = op++; 180 while (((ch = *in++) != 0) && (max_out-- > 1)) { 181 if (ch == 0) { 182 if ((*lp = len) != 0) 183 *op++ = 0; 184 break; 185 } 186 if (ch == '.') { 187 *lp = len; 188 lp = op++; 189 len = 0; 190 } else { 191 *op++ = ch; 192 len++; 193 } 194 } 195 *lp = len; 196 if (len != 0) 197 *op = 0; 198 199 /*LINTED E_PTRDIFF_OVERFLOW*/ 200 return (op - out); 201 } 202 203 /* 204 * smb_first_level_name_decode 205 * 206 * The null terminated string "in" is the name to decode. The output 207 * is placed in the name_entry structure "name". 208 * 209 * The scope field is a series of length designated labels as described 210 * in the "Domain name representation and compression" section of RFC883. 211 * The two high order two bits of the length field must be zero, the 212 * remaining six bits contain the field length. The total length of the 213 * domain name is restricted to 255 octets but note that the trailing 214 * root label and its dot are not printed. When converting the labels, 215 * the length fields are replaced by dots. 216 * 217 * Returns the number of bytes scanned or -1 to indicate an error. 218 */ 219 int 220 netbios_first_level_name_decode(char *in, char *name, char *scope) 221 { 222 unsigned int length; 223 char c1, c2; 224 char *cp; 225 char *out; 226 227 cp = in; 228 229 if ((length = *cp++) != 0x20) { 230 return (-1); 231 } 232 233 out = name; 234 while (length > 0) { 235 c1 = *cp++; 236 c2 = *cp++; 237 238 if ('A' <= c1 && c1 <= 'P' && 'A' <= c2 && c2 <= 'P') { 239 c1 -= 'A'; 240 c2 -= 'A'; 241 *out++ = (c1 << 4) | (c2); 242 } else { 243 return (-1); /* conversion error */ 244 } 245 length -= 2; 246 } 247 248 /* 249 * Don't bother decoding the scope. Not supported. 250 */ 251 if ((length = *cp++) != 0) 252 return (-1); 253 scope[0] = '\0'; 254 255 /*LINTED E_PTRDIFF_OVERFLOW*/ 256 return (cp - in); 257 } 258 259 /* 260 * smb_netbios_name_isvalid 261 * 262 * This function is provided to be used by session service 263 * which runs in kernel in order to hide name_entry definition. 264 * 265 * It returns the decoded name in the provided buffer as 'out' 266 * if it's not null. 267 * 268 * Returns 0 if decode fails, 1 if it succeeds. 269 */ 270 int 271 netbios_name_isvalid(char *in, char *out) 272 { 273 char name[NETBIOS_NAME_SZ]; 274 char scope[NETBIOS_DOMAIN_NAME_MAX]; 275 276 if (netbios_first_level_name_decode(in, name, scope) < 0) 277 return (0); 278 279 if (out) 280 (void) strlcpy(out, name, NETBIOS_NAME_SZ); 281 282 return (1); 283 } 284