1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 22148c5f43SAlan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23*b819cea2SGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw #include <ctype.h> 27da6c28aaSamw #include <stdio.h> 28148c5f43SAlan Wright #include <stdarg.h> 29148c5f43SAlan Wright #include <unistd.h> 30148c5f43SAlan Wright #include <sys/fcntl.h> 31da6c28aaSamw #include <string.h> 321fcced4cSJordan Brown #include <strings.h> 33da6c28aaSamw #include <stdlib.h> 34da6c28aaSamw #include <pthread.h> 35da6c28aaSamw #include <sys/varargs.h> 36da6c28aaSamw #include <sys/types.h> 376d57f833SAlan Wright #include <sys/mnttab.h> 38b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <tiuser.h> 39b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <netconfig.h> 40b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <netdir.h> 41b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/systeminfo.h> 42b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/utsname.h> 436d57f833SAlan Wright #include <libzfs.h> 441fcced4cSJordan Brown #include <dlfcn.h> 45148c5f43SAlan Wright #include <time.h> 46148c5f43SAlan Wright #include <syslog.h> 476d57f833SAlan Wright #include <smbsrv/string.h> 486d57f833SAlan Wright #include <smbsrv/libsmb.h> 49b89a8333Snatalie li - Sun Microsystems - Irvine United States 501fcced4cSJordan Brown #define SMB_LIB_ALT "/usr/lib/smbsrv/libsmbex.so" 511fcced4cSJordan Brown 52b89a8333Snatalie li - Sun Microsystems - Irvine United States static boolean_t smb_netgroup_match(struct nd_hostservlist *, char *, int); 53b89a8333Snatalie li - Sun Microsystems - Irvine United States 54b89a8333Snatalie li - Sun Microsystems - Irvine United States extern int __multi_innetgr(); 55b89a8333Snatalie li - Sun Microsystems - Irvine United States extern int __netdir_getbyaddr_nosrv(struct netconfig *, 56b89a8333Snatalie li - Sun Microsystems - Irvine United States struct nd_hostservlist **, struct netbuf *); 57da6c28aaSamw 58da6c28aaSamw #define C2H(c) "0123456789ABCDEF"[(c)] 59da6c28aaSamw #define H2C(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \ 60da6c28aaSamw ((c) >= 'a' && (c) <= 'f') ? ((c) - 'a' + 10) : \ 61da6c28aaSamw ((c) >= 'A' && (c) <= 'F') ? ((c) - 'A' + 10) : \ 62da6c28aaSamw '\0') 63da6c28aaSamw #define DEFAULT_SBOX_SIZE 256 64da6c28aaSamw 65da6c28aaSamw /* 66da6c28aaSamw * 67da6c28aaSamw * hexdump 68da6c28aaSamw * 69da6c28aaSamw * Simple hex dump display function. Displays nbytes of buffer in hex and 70da6c28aaSamw * printable format. Non-printing characters are shown as '.'. It is safe 71da6c28aaSamw * to pass a null pointer. Each line begins with the offset. If nbytes is 72da6c28aaSamw * 0, the line will be blank except for the offset. Example output: 73da6c28aaSamw * 74da6c28aaSamw * 00000000 54 68 69 73 20 69 73 20 61 20 70 72 6F 67 72 61 This is a progra 75da6c28aaSamw * 00000010 6D 20 74 65 73 74 2E 00 m test.. 76da6c28aaSamw * 77da6c28aaSamw */ 78da6c28aaSamw void 79dc20a302Sas200622 hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start) 80da6c28aaSamw { 81da6c28aaSamw static char *hex = "0123456789ABCDEF"; 82da6c28aaSamw int i, count; 83da6c28aaSamw int offset; 84da6c28aaSamw unsigned char *p; 85da6c28aaSamw char ascbuf[64]; 86da6c28aaSamw char hexbuf[64]; 87da6c28aaSamw char *ap = ascbuf; 88da6c28aaSamw char *hp = hexbuf; 89da6c28aaSamw 90dc20a302Sas200622 if ((p = buffer) == NULL) 91da6c28aaSamw return; 92da6c28aaSamw 93da6c28aaSamw offset = *start; 94da6c28aaSamw 95da6c28aaSamw *ap = '\0'; 96da6c28aaSamw *hp = '\0'; 97da6c28aaSamw count = 0; 98da6c28aaSamw 99da6c28aaSamw for (i = 0; i < nbytes; ++i) { 100da6c28aaSamw if (i && (i % 16) == 0) { 101dc20a302Sas200622 smb_tracef("%06X %s %s", offset, hexbuf, ascbuf); 102da6c28aaSamw ap = ascbuf; 103da6c28aaSamw hp = hexbuf; 104da6c28aaSamw count = 0; 105da6c28aaSamw offset += 16; 106da6c28aaSamw } 107da6c28aaSamw 108da6c28aaSamw ap += sprintf(ap, "%c", 109da6c28aaSamw (*p >= 0x20 && *p < 0x7F) ? *p : '.'); 110da6c28aaSamw hp += sprintf(hp, " %c%c", 111da6c28aaSamw hex[(*p >> 4) & 0x0F], hex[(*p & 0x0F)]); 112da6c28aaSamw ++p; 113da6c28aaSamw ++count; 114da6c28aaSamw } 115da6c28aaSamw 116da6c28aaSamw if (count) { 117dc20a302Sas200622 smb_tracef("%06X %-48s %s", offset, hexbuf, ascbuf); 118da6c28aaSamw offset += count; 119da6c28aaSamw } 120da6c28aaSamw 121da6c28aaSamw *start = offset; 122da6c28aaSamw } 123da6c28aaSamw 124da6c28aaSamw void 125da6c28aaSamw hexdump(unsigned char *buffer, int nbytes) 126da6c28aaSamw { 127da6c28aaSamw unsigned long start = 0; 128da6c28aaSamw 129dc20a302Sas200622 hexdump_offset(buffer, nbytes, &start); 130da6c28aaSamw } 131da6c28aaSamw 132da6c28aaSamw /* 133da6c28aaSamw * bintohex 134da6c28aaSamw * 135da6c28aaSamw * Converts the given binary data (srcbuf) to 136da6c28aaSamw * its equivalent hex chars (hexbuf). 137da6c28aaSamw * 138da6c28aaSamw * hexlen should be at least twice as srclen. 139da6c28aaSamw * if hexbuf is not big enough returns 0. 140da6c28aaSamw * otherwise returns number of valid chars in 141da6c28aaSamw * hexbuf which is srclen * 2. 142da6c28aaSamw */ 143da6c28aaSamw size_t 144da6c28aaSamw bintohex(const char *srcbuf, size_t srclen, 145da6c28aaSamw char *hexbuf, size_t hexlen) 146da6c28aaSamw { 147da6c28aaSamw size_t outlen; 148da6c28aaSamw char c; 149da6c28aaSamw 150da6c28aaSamw outlen = srclen << 1; 151da6c28aaSamw 152da6c28aaSamw if (hexlen < outlen) 153da6c28aaSamw return (0); 154da6c28aaSamw 155da6c28aaSamw while (srclen-- > 0) { 156da6c28aaSamw c = *srcbuf++; 157da6c28aaSamw *hexbuf++ = C2H(c & 0xF); 158da6c28aaSamw *hexbuf++ = C2H((c >> 4) & 0xF); 159da6c28aaSamw } 160da6c28aaSamw 161da6c28aaSamw return (outlen); 162da6c28aaSamw } 163da6c28aaSamw 164da6c28aaSamw /* 165da6c28aaSamw * hextobin 166da6c28aaSamw * 167da6c28aaSamw * Converts hex to binary. 168da6c28aaSamw * 169da6c28aaSamw * Assuming hexbuf only contains hex digits (chars) 170da6c28aaSamw * this function convert every two bytes of hexbuf 171da6c28aaSamw * to one byte and put it in dstbuf. 172da6c28aaSamw * 173da6c28aaSamw * hexlen should be an even number. 174da6c28aaSamw * dstlen should be at least half of hexlen. 175da6c28aaSamw * 176da6c28aaSamw * Returns 0 if sizes are not correct, otherwise 177da6c28aaSamw * returns the number of converted bytes in dstbuf 178da6c28aaSamw * which is half of hexlen. 179da6c28aaSamw */ 180da6c28aaSamw size_t 181da6c28aaSamw hextobin(const char *hexbuf, size_t hexlen, 182da6c28aaSamw char *dstbuf, size_t dstlen) 183da6c28aaSamw { 184da6c28aaSamw size_t outlen; 185da6c28aaSamw 186da6c28aaSamw if ((hexlen % 2) != 0) 187da6c28aaSamw return (0); 188da6c28aaSamw 189da6c28aaSamw outlen = hexlen >> 1; 190da6c28aaSamw if (dstlen < outlen) 191da6c28aaSamw return (0); 192da6c28aaSamw 193da6c28aaSamw while (hexlen > 0) { 194da6c28aaSamw *dstbuf = H2C(*hexbuf) & 0x0F; 195da6c28aaSamw hexbuf++; 196da6c28aaSamw *dstbuf++ |= (H2C(*hexbuf) << 4) & 0xF0; 197da6c28aaSamw hexbuf++; 198da6c28aaSamw 199da6c28aaSamw hexlen -= 2; 200da6c28aaSamw } 201da6c28aaSamw 202da6c28aaSamw return (outlen); 203da6c28aaSamw } 204da6c28aaSamw 205da6c28aaSamw /* 2068d7e4166Sjose borrego * Trim leading and trailing characters in the set defined by class 2078d7e4166Sjose borrego * from a buffer containing a null-terminated string. 2088d7e4166Sjose borrego * For example, if the input buffer contained "ABtext23" and class 2098d7e4166Sjose borrego * contains "ABC123", the buffer will contain "text" on return. 2108d7e4166Sjose borrego * 2118d7e4166Sjose borrego * This function modifies the contents of buf in place and returns 2128d7e4166Sjose borrego * a pointer to buf. 2138d7e4166Sjose borrego */ 2148d7e4166Sjose borrego char * 2158d7e4166Sjose borrego strtrim(char *buf, const char *class) 2168d7e4166Sjose borrego { 2178d7e4166Sjose borrego char *p = buf; 2188d7e4166Sjose borrego char *q = buf; 2198d7e4166Sjose borrego 2208d7e4166Sjose borrego if (buf == NULL) 2218d7e4166Sjose borrego return (NULL); 2228d7e4166Sjose borrego 2238d7e4166Sjose borrego p += strspn(p, class); 2248d7e4166Sjose borrego 2258d7e4166Sjose borrego if (p != buf) { 2268d7e4166Sjose borrego while ((*q = *p++) != '\0') 2278d7e4166Sjose borrego ++q; 2288d7e4166Sjose borrego } 2298d7e4166Sjose borrego 2308d7e4166Sjose borrego while (q != buf) { 2318d7e4166Sjose borrego --q; 2328d7e4166Sjose borrego if (strspn(q, class) == 0) 2338d7e4166Sjose borrego return (buf); 2348d7e4166Sjose borrego *q = '\0'; 2358d7e4166Sjose borrego } 2368d7e4166Sjose borrego 2378d7e4166Sjose borrego return (buf); 2388d7e4166Sjose borrego } 2398d7e4166Sjose borrego 2408d7e4166Sjose borrego /* 2418d7e4166Sjose borrego * Strip the characters in the set defined by class from a buffer 2428d7e4166Sjose borrego * containing a null-terminated string. 2438d7e4166Sjose borrego * For example, if the input buffer contained "XYA 1textZ string3" 2448d7e4166Sjose borrego * and class contains "123XYZ", the buffer will contain "A text string" 2458d7e4166Sjose borrego * on return. 2468d7e4166Sjose borrego * 2478d7e4166Sjose borrego * This function modifies the contents of buf in place and returns 2488d7e4166Sjose borrego * a pointer to buf. 2498d7e4166Sjose borrego */ 2508d7e4166Sjose borrego char * 2518d7e4166Sjose borrego strstrip(char *buf, const char *class) 2528d7e4166Sjose borrego { 2538d7e4166Sjose borrego char *p = buf; 2548d7e4166Sjose borrego char *q = buf; 2558d7e4166Sjose borrego 2568d7e4166Sjose borrego if (buf == NULL) 2578d7e4166Sjose borrego return (NULL); 2588d7e4166Sjose borrego 2598d7e4166Sjose borrego while (*p) { 2608d7e4166Sjose borrego p += strspn(p, class); 2618d7e4166Sjose borrego *q++ = *p++; 2628d7e4166Sjose borrego } 2638d7e4166Sjose borrego 2648d7e4166Sjose borrego *q = '\0'; 2658d7e4166Sjose borrego return (buf); 2668d7e4166Sjose borrego } 2678d7e4166Sjose borrego 2688d7e4166Sjose borrego /* 269da6c28aaSamw * trim_whitespace 270da6c28aaSamw * 271da6c28aaSamw * Trim leading and trailing whitespace chars (as defined by isspace) 272da6c28aaSamw * from a buffer. Example; if the input buffer contained " text ", 273da6c28aaSamw * it will contain "text", when we return. We assume that the buffer 274da6c28aaSamw * contains a null terminated string. A pointer to the buffer is 275da6c28aaSamw * returned. 276da6c28aaSamw */ 277da6c28aaSamw char * 278da6c28aaSamw trim_whitespace(char *buf) 279da6c28aaSamw { 280da6c28aaSamw char *p = buf; 281da6c28aaSamw char *q = buf; 282da6c28aaSamw 283dc20a302Sas200622 if (buf == NULL) 284dc20a302Sas200622 return (NULL); 285da6c28aaSamw 286da6c28aaSamw while (*p && isspace(*p)) 287da6c28aaSamw ++p; 288da6c28aaSamw 289da6c28aaSamw while ((*q = *p++) != 0) 290da6c28aaSamw ++q; 291da6c28aaSamw 292da6c28aaSamw if (q != buf) { 293da6c28aaSamw while ((--q, isspace(*q)) != 0) 294da6c28aaSamw *q = '\0'; 295da6c28aaSamw } 296da6c28aaSamw 297da6c28aaSamw return (buf); 298da6c28aaSamw } 299da6c28aaSamw 300da6c28aaSamw /* 301da6c28aaSamw * This is the hash mechanism used to encrypt passwords for commands like 302da6c28aaSamw * SamrSetUserInformation. It uses a 256 byte s-box. 303da6c28aaSamw */ 304da6c28aaSamw void 305da6c28aaSamw rand_hash( 306da6c28aaSamw unsigned char *data, 307da6c28aaSamw size_t datalen, 308da6c28aaSamw unsigned char *key, 309da6c28aaSamw size_t keylen) 310da6c28aaSamw { 311da6c28aaSamw unsigned char sbox[DEFAULT_SBOX_SIZE]; 312da6c28aaSamw unsigned char tmp; 313da6c28aaSamw unsigned char index_i = 0; 314da6c28aaSamw unsigned char index_j = 0; 315da6c28aaSamw unsigned char j = 0; 316da6c28aaSamw int i; 317da6c28aaSamw 318da6c28aaSamw for (i = 0; i < DEFAULT_SBOX_SIZE; ++i) 319da6c28aaSamw sbox[i] = (unsigned char)i; 320da6c28aaSamw 321da6c28aaSamw for (i = 0; i < DEFAULT_SBOX_SIZE; ++i) { 322da6c28aaSamw j += (sbox[i] + key[i % keylen]); 323da6c28aaSamw 324da6c28aaSamw tmp = sbox[i]; 325da6c28aaSamw sbox[i] = sbox[j]; 326da6c28aaSamw sbox[j] = tmp; 327da6c28aaSamw } 328da6c28aaSamw 329da6c28aaSamw for (i = 0; i < datalen; ++i) { 330da6c28aaSamw index_i++; 331da6c28aaSamw index_j += sbox[index_i]; 332da6c28aaSamw 333da6c28aaSamw tmp = sbox[index_i]; 334da6c28aaSamw sbox[index_i] = sbox[index_j]; 335da6c28aaSamw sbox[index_j] = tmp; 336da6c28aaSamw 337da6c28aaSamw tmp = sbox[index_i] + sbox[index_j]; 338da6c28aaSamw data[i] = data[i] ^ sbox[tmp]; 339da6c28aaSamw } 340da6c28aaSamw } 341b89a8333Snatalie li - Sun Microsystems - Irvine United States 342b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 343b89a8333Snatalie li - Sun Microsystems - Irvine United States * smb_chk_hostaccess 344b89a8333Snatalie li - Sun Microsystems - Irvine United States * 345148c5f43SAlan Wright * Determines whether the specified host is in the given access list. 346148c5f43SAlan Wright * 347b89a8333Snatalie li - Sun Microsystems - Irvine United States * We match on aliases of the hostname as well as on the canonical name. 348b89a8333Snatalie li - Sun Microsystems - Irvine United States * Names in the access list may be either hosts or netgroups; they're 349b89a8333Snatalie li - Sun Microsystems - Irvine United States * not distinguished syntactically. We check for hosts first because 350b89a8333Snatalie li - Sun Microsystems - Irvine United States * it's cheaper (just M*N strcmp()s), then try netgroups. 351b89a8333Snatalie li - Sun Microsystems - Irvine United States * 352b89a8333Snatalie li - Sun Microsystems - Irvine United States * Function returns: 353148c5f43SAlan Wright * -1 for "all" (list is empty "" or "*") 354148c5f43SAlan Wright * 0 not found (host is not in the list or list is NULL) 355b89a8333Snatalie li - Sun Microsystems - Irvine United States * 1 found 3567f667e74Sjose borrego * 357b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 358b89a8333Snatalie li - Sun Microsystems - Irvine United States int 3597f667e74Sjose borrego smb_chk_hostaccess(smb_inaddr_t *ipaddr, char *access_list) 360b89a8333Snatalie li - Sun Microsystems - Irvine United States { 3619b241b4eSYuri Pankov char addr[INET_ADDRSTRLEN]; 3629b241b4eSYuri Pankov char buff[256]; 3639b241b4eSYuri Pankov char *cstr = access_list, *gr = access_list; 364b89a8333Snatalie li - Sun Microsystems - Irvine United States char *host; 3652807a6ecSYuri Pankov int clres; 3669b241b4eSYuri Pankov int i; 3679b241b4eSYuri Pankov int nentries = 0; 3689b241b4eSYuri Pankov int off; 3699b241b4eSYuri Pankov int response; 3709b241b4eSYuri Pankov int sbr = 0; 371b89a8333Snatalie li - Sun Microsystems - Irvine United States struct nd_hostservlist *clnames; 372b89a8333Snatalie li - Sun Microsystems - Irvine United States struct in_addr inaddr; 373b89a8333Snatalie li - Sun Microsystems - Irvine United States struct sockaddr_in sa; 3749b241b4eSYuri Pankov struct sockaddr_in6 sa6; 375b89a8333Snatalie li - Sun Microsystems - Irvine United States struct netbuf buf; 376b89a8333Snatalie li - Sun Microsystems - Irvine United States struct netconfig *config; 3779b241b4eSYuri Pankov struct netent n, *np; 378b89a8333Snatalie li - Sun Microsystems - Irvine United States 379148c5f43SAlan Wright if (access_list == NULL) 380148c5f43SAlan Wright return (0); 3817f667e74Sjose borrego 3829b241b4eSYuri Pankov /* If access list is empty or "*" - then it's "all" */ 383148c5f43SAlan Wright if (*access_list == '\0' || strcmp(access_list, "*") == 0) 384b89a8333Snatalie li - Sun Microsystems - Irvine United States return (-1); 385b89a8333Snatalie li - Sun Microsystems - Irvine United States 3869b241b4eSYuri Pankov switch (ipaddr->a_family) { 3879b241b4eSYuri Pankov case AF_INET: 3889b241b4eSYuri Pankov inaddr.s_addr = ipaddr->a_ipv4; 389b89a8333Snatalie li - Sun Microsystems - Irvine United States sa.sin_family = AF_INET; 390b89a8333Snatalie li - Sun Microsystems - Irvine United States sa.sin_port = 0; 391b89a8333Snatalie li - Sun Microsystems - Irvine United States sa.sin_addr = inaddr; 392b89a8333Snatalie li - Sun Microsystems - Irvine United States buf.len = buf.maxlen = sizeof (sa); 393b89a8333Snatalie li - Sun Microsystems - Irvine United States buf.buf = (char *)&sa; 394b89a8333Snatalie li - Sun Microsystems - Irvine United States config = getnetconfigent("tcp"); 3959b241b4eSYuri Pankov break; 3969b241b4eSYuri Pankov case AF_INET6: 3979b241b4eSYuri Pankov sa6.sin6_family = AF_INET6; 3989b241b4eSYuri Pankov sa6.sin6_port = 0; 3999b241b4eSYuri Pankov sa6.sin6_addr = ipaddr->a_ipv6; 4009b241b4eSYuri Pankov buf.len = buf.maxlen = sizeof (sa6); 4019b241b4eSYuri Pankov buf.buf = (char *)&sa6; 4029b241b4eSYuri Pankov config = getnetconfigent("tcp6"); 4039b241b4eSYuri Pankov break; 4049b241b4eSYuri Pankov default: 4059b241b4eSYuri Pankov return (1); 4069b241b4eSYuri Pankov } 4079b241b4eSYuri Pankov 408b89a8333Snatalie li - Sun Microsystems - Irvine United States if (config == NULL) 409b89a8333Snatalie li - Sun Microsystems - Irvine United States return (1); 410b89a8333Snatalie li - Sun Microsystems - Irvine United States 4119b241b4eSYuri Pankov /* Try to lookup client hostname */ 4122807a6ecSYuri Pankov clres = __netdir_getbyaddr_nosrv(config, &clnames, &buf); 413b89a8333Snatalie li - Sun Microsystems - Irvine United States freenetconfigent(config); 414b89a8333Snatalie li - Sun Microsystems - Irvine United States 4159b241b4eSYuri Pankov for (;;) { 4169b241b4eSYuri Pankov if ((cstr = strpbrk(cstr, "[]:")) != NULL) { 4179b241b4eSYuri Pankov switch (*cstr) { 4189b241b4eSYuri Pankov case '[': 4199b241b4eSYuri Pankov case ']': 4209b241b4eSYuri Pankov sbr = !sbr; 4219b241b4eSYuri Pankov cstr++; 4229b241b4eSYuri Pankov continue; 4239b241b4eSYuri Pankov case ':': 4249b241b4eSYuri Pankov if (sbr) { 4259b241b4eSYuri Pankov cstr++; 4269b241b4eSYuri Pankov continue; 4279b241b4eSYuri Pankov } 4289b241b4eSYuri Pankov *cstr = '\0'; 4299b241b4eSYuri Pankov } 4309b241b4eSYuri Pankov } 431b89a8333Snatalie li - Sun Microsystems - Irvine United States 432b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 4339b241b4eSYuri Pankov * If the list name has a '-' prepended then a match of 4349b241b4eSYuri Pankov * the following name implies failure instead of success. 435b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 436b89a8333Snatalie li - Sun Microsystems - Irvine United States if (*gr == '-') { 437b89a8333Snatalie li - Sun Microsystems - Irvine United States response = 0; 438b89a8333Snatalie li - Sun Microsystems - Irvine United States gr++; 439b89a8333Snatalie li - Sun Microsystems - Irvine United States } else { 440b89a8333Snatalie li - Sun Microsystems - Irvine United States response = 1; 441b89a8333Snatalie li - Sun Microsystems - Irvine United States } 442b89a8333Snatalie li - Sun Microsystems - Irvine United States 443b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 4449b241b4eSYuri Pankov * First check if we have '@' entry, as it doesn't 4459b241b4eSYuri Pankov * require client hostname. 4462807a6ecSYuri Pankov */ 4479b241b4eSYuri Pankov if (*gr == '@') { 4489b241b4eSYuri Pankov gr++; 4499b241b4eSYuri Pankov 4509b241b4eSYuri Pankov if (!isdigit(*gr) && *gr != '[') { 4519b241b4eSYuri Pankov /* Netname support */ 4529b241b4eSYuri Pankov if ((np = getnetbyname_r(gr, &n, buff, 4539b241b4eSYuri Pankov sizeof (buff))) != NULL && 4549b241b4eSYuri Pankov np->n_net != 0) { 4559b241b4eSYuri Pankov while ((np->n_net & 0xFF000000u) == 0) 4569b241b4eSYuri Pankov np->n_net <<= 8; 4579b241b4eSYuri Pankov np->n_net = htonl(np->n_net); 4589b241b4eSYuri Pankov if (inet_ntop(AF_INET, &np->n_net, addr, 4599b241b4eSYuri Pankov INET_ADDRSTRLEN) == NULL) 4609b241b4eSYuri Pankov break; 4619b241b4eSYuri Pankov if (inet_matchaddr(buf.buf, addr)) 4622807a6ecSYuri Pankov return (response); 4639b241b4eSYuri Pankov } 4649b241b4eSYuri Pankov } else { 4659b241b4eSYuri Pankov if (inet_matchaddr(buf.buf, gr)) 4669b241b4eSYuri Pankov return (response); 4679b241b4eSYuri Pankov } 4689b241b4eSYuri Pankov 4699b241b4eSYuri Pankov if (cstr == NULL) 4709b241b4eSYuri Pankov break; 4719b241b4eSYuri Pankov 4729b241b4eSYuri Pankov gr = ++cstr; 4739b241b4eSYuri Pankov 4749b241b4eSYuri Pankov continue; 4759b241b4eSYuri Pankov } 4769b241b4eSYuri Pankov 4772807a6ecSYuri Pankov /* 4782807a6ecSYuri Pankov * No other checks can be performed if client address 4792807a6ecSYuri Pankov * can't be resolved. 4802807a6ecSYuri Pankov */ 4819b241b4eSYuri Pankov if (clres) { 4829b241b4eSYuri Pankov if (cstr == NULL) 4839b241b4eSYuri Pankov break; 4849b241b4eSYuri Pankov 4859b241b4eSYuri Pankov gr = ++cstr; 4869b241b4eSYuri Pankov 4872807a6ecSYuri Pankov continue; 4889b241b4eSYuri Pankov } 4899b241b4eSYuri Pankov 4909b241b4eSYuri Pankov /* Otherwise loop through all client hostname aliases */ 491b89a8333Snatalie li - Sun Microsystems - Irvine United States for (i = 0; i < clnames->h_cnt; i++) { 492b89a8333Snatalie li - Sun Microsystems - Irvine United States host = clnames->h_hostservs[i].h_host; 493b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 494b89a8333Snatalie li - Sun Microsystems - Irvine United States * If the list name begins with a dot then 495b89a8333Snatalie li - Sun Microsystems - Irvine United States * do a domain name suffix comparison. 496b89a8333Snatalie li - Sun Microsystems - Irvine United States * A single dot matches any name with no 497b89a8333Snatalie li - Sun Microsystems - Irvine United States * suffix. 498b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 499b89a8333Snatalie li - Sun Microsystems - Irvine United States if (*gr == '.') { 5009b241b4eSYuri Pankov if (*(gr + 1) == '\0') { 501b89a8333Snatalie li - Sun Microsystems - Irvine United States if (strchr(host, '.') == NULL) 502b89a8333Snatalie li - Sun Microsystems - Irvine United States return (response); 503b89a8333Snatalie li - Sun Microsystems - Irvine United States } else { 504b89a8333Snatalie li - Sun Microsystems - Irvine United States off = strlen(host) - strlen(gr); 505b89a8333Snatalie li - Sun Microsystems - Irvine United States if (off > 0 && 506b89a8333Snatalie li - Sun Microsystems - Irvine United States strcasecmp(host + off, gr) == 0) { 507b89a8333Snatalie li - Sun Microsystems - Irvine United States return (response); 508b89a8333Snatalie li - Sun Microsystems - Irvine United States } 509b89a8333Snatalie li - Sun Microsystems - Irvine United States } 510b89a8333Snatalie li - Sun Microsystems - Irvine United States } else { 5119b241b4eSYuri Pankov /* Just do a hostname match */ 512b89a8333Snatalie li - Sun Microsystems - Irvine United States if (strcasecmp(gr, host) == 0) 513b89a8333Snatalie li - Sun Microsystems - Irvine United States return (response); 514b89a8333Snatalie li - Sun Microsystems - Irvine United States } 515b89a8333Snatalie li - Sun Microsystems - Irvine United States } 516b89a8333Snatalie li - Sun Microsystems - Irvine United States 517b89a8333Snatalie li - Sun Microsystems - Irvine United States nentries++; 5189b241b4eSYuri Pankov 5199b241b4eSYuri Pankov if (cstr == NULL) 5209b241b4eSYuri Pankov break; 5219b241b4eSYuri Pankov 5229b241b4eSYuri Pankov gr = ++cstr; 523b89a8333Snatalie li - Sun Microsystems - Irvine United States } 524b89a8333Snatalie li - Sun Microsystems - Irvine United States 5252807a6ecSYuri Pankov if (clres) 5262807a6ecSYuri Pankov return (0); 527b89a8333Snatalie li - Sun Microsystems - Irvine United States 5282807a6ecSYuri Pankov return (smb_netgroup_match(clnames, access_list, nentries)); 529b89a8333Snatalie li - Sun Microsystems - Irvine United States } 530b89a8333Snatalie li - Sun Microsystems - Irvine United States 531b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 532b89a8333Snatalie li - Sun Microsystems - Irvine United States * smb_netgroup_match 533b89a8333Snatalie li - Sun Microsystems - Irvine United States * 534b89a8333Snatalie li - Sun Microsystems - Irvine United States * Check whether any of the hostnames in clnames are 535b89a8333Snatalie li - Sun Microsystems - Irvine United States * members (or non-members) of the netgroups in glist. 536b89a8333Snatalie li - Sun Microsystems - Irvine United States * Since the innetgr lookup is rather expensive, the 537b89a8333Snatalie li - Sun Microsystems - Irvine United States * result is cached. The cached entry is valid only 538b89a8333Snatalie li - Sun Microsystems - Irvine United States * for VALID_TIME seconds. This works well because 539b89a8333Snatalie li - Sun Microsystems - Irvine United States * typically these lookups occur in clusters when 540b89a8333Snatalie li - Sun Microsystems - Irvine United States * a client is mounting. 541b89a8333Snatalie li - Sun Microsystems - Irvine United States * 542b89a8333Snatalie li - Sun Microsystems - Irvine United States * Note that this routine establishes a host membership 543b89a8333Snatalie li - Sun Microsystems - Irvine United States * in a list of netgroups - we've no idea just which 544b89a8333Snatalie li - Sun Microsystems - Irvine United States * netgroup in the list it is a member of. 545b89a8333Snatalie li - Sun Microsystems - Irvine United States * 546b89a8333Snatalie li - Sun Microsystems - Irvine United States * glist is a character array containing grc strings 547b89a8333Snatalie li - Sun Microsystems - Irvine United States * representing netgroup names (optionally prefixed 548b89a8333Snatalie li - Sun Microsystems - Irvine United States * with '-'). Each string is ended with '\0' and 549b89a8333Snatalie li - Sun Microsystems - Irvine United States * followed immediately by the next string. 550b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 551b89a8333Snatalie li - Sun Microsystems - Irvine United States static boolean_t 552b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_netgroup_match(struct nd_hostservlist *clnames, char *glist, int grc) 553b89a8333Snatalie li - Sun Microsystems - Irvine United States { 554b89a8333Snatalie li - Sun Microsystems - Irvine United States char **grl; 555b89a8333Snatalie li - Sun Microsystems - Irvine United States char *gr; 556b89a8333Snatalie li - Sun Microsystems - Irvine United States int nhosts = clnames->h_cnt; 557b89a8333Snatalie li - Sun Microsystems - Irvine United States char *host; 558b89a8333Snatalie li - Sun Microsystems - Irvine United States int i, j, n; 559b89a8333Snatalie li - Sun Microsystems - Irvine United States boolean_t response; 560b89a8333Snatalie li - Sun Microsystems - Irvine United States boolean_t belong = B_FALSE; 561b89a8333Snatalie li - Sun Microsystems - Irvine United States static char *domain = NULL; 562b89a8333Snatalie li - Sun Microsystems - Irvine United States 563b89a8333Snatalie li - Sun Microsystems - Irvine United States if (domain == NULL) { 564b89a8333Snatalie li - Sun Microsystems - Irvine United States int ssize; 565b89a8333Snatalie li - Sun Microsystems - Irvine United States 566b89a8333Snatalie li - Sun Microsystems - Irvine United States domain = malloc(SYS_NMLN); 567b89a8333Snatalie li - Sun Microsystems - Irvine United States if (domain == NULL) 568b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 569b89a8333Snatalie li - Sun Microsystems - Irvine United States 570b89a8333Snatalie li - Sun Microsystems - Irvine United States ssize = sysinfo(SI_SRPC_DOMAIN, domain, SYS_NMLN); 571b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ssize > SYS_NMLN) { 572b89a8333Snatalie li - Sun Microsystems - Irvine United States free(domain); 573b89a8333Snatalie li - Sun Microsystems - Irvine United States domain = malloc(ssize); 574b89a8333Snatalie li - Sun Microsystems - Irvine United States if (domain == NULL) 575b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 576b89a8333Snatalie li - Sun Microsystems - Irvine United States ssize = sysinfo(SI_SRPC_DOMAIN, domain, ssize); 577b89a8333Snatalie li - Sun Microsystems - Irvine United States } 578b89a8333Snatalie li - Sun Microsystems - Irvine United States /* Check for error in syscall or NULL domain name */ 579b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ssize <= 1) 580b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 581b89a8333Snatalie li - Sun Microsystems - Irvine United States } 582b89a8333Snatalie li - Sun Microsystems - Irvine United States 583b89a8333Snatalie li - Sun Microsystems - Irvine United States grl = calloc(grc, sizeof (char *)); 584b89a8333Snatalie li - Sun Microsystems - Irvine United States if (grl == NULL) 585b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 586b89a8333Snatalie li - Sun Microsystems - Irvine United States 587b89a8333Snatalie li - Sun Microsystems - Irvine United States for (i = 0, gr = glist; i < grc && !belong; ) { 588b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 589b89a8333Snatalie li - Sun Microsystems - Irvine United States * If the netgroup name has a '-' prepended 590b89a8333Snatalie li - Sun Microsystems - Irvine United States * then a match of this name implies a failure 591b89a8333Snatalie li - Sun Microsystems - Irvine United States * instead of success. 592b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 593b89a8333Snatalie li - Sun Microsystems - Irvine United States response = (*gr != '-') ? B_TRUE : B_FALSE; 594b89a8333Snatalie li - Sun Microsystems - Irvine United States 595b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 596b89a8333Snatalie li - Sun Microsystems - Irvine United States * Subsequent names with or without a '-' (but no mix) 597b89a8333Snatalie li - Sun Microsystems - Irvine United States * can be grouped together for a single check. 598b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 599b89a8333Snatalie li - Sun Microsystems - Irvine United States for (n = 0; i < grc; i++, n++, gr += strlen(gr) + 1) { 600b89a8333Snatalie li - Sun Microsystems - Irvine United States if ((response && *gr == '-') || 601b89a8333Snatalie li - Sun Microsystems - Irvine United States (!response && *gr != '-')) 602b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 603b89a8333Snatalie li - Sun Microsystems - Irvine United States 604b89a8333Snatalie li - Sun Microsystems - Irvine United States grl[n] = response ? gr : gr + 1; 605b89a8333Snatalie li - Sun Microsystems - Irvine United States } 606b89a8333Snatalie li - Sun Microsystems - Irvine United States 607b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 608b89a8333Snatalie li - Sun Microsystems - Irvine United States * Check the netgroup for each 609b89a8333Snatalie li - Sun Microsystems - Irvine United States * of the hosts names (usually just one). 610b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 611b89a8333Snatalie li - Sun Microsystems - Irvine United States for (j = 0; j < nhosts && !belong; j++) { 612b89a8333Snatalie li - Sun Microsystems - Irvine United States host = clnames->h_hostservs[j].h_host; 613b89a8333Snatalie li - Sun Microsystems - Irvine United States if (__multi_innetgr(n, grl, 1, &host, 0, NULL, 614b89a8333Snatalie li - Sun Microsystems - Irvine United States 1, &domain)) 615b89a8333Snatalie li - Sun Microsystems - Irvine United States belong = B_TRUE; 616b89a8333Snatalie li - Sun Microsystems - Irvine United States } 617b89a8333Snatalie li - Sun Microsystems - Irvine United States } 618b89a8333Snatalie li - Sun Microsystems - Irvine United States 619b89a8333Snatalie li - Sun Microsystems - Irvine United States free(grl); 620b89a8333Snatalie li - Sun Microsystems - Irvine United States return (belong ? response : B_FALSE); 621b89a8333Snatalie li - Sun Microsystems - Irvine United States } 6226d57f833SAlan Wright 6236d57f833SAlan Wright /* 6246d57f833SAlan Wright * Resolve the ZFS dataset from a path. 62529bd2886SAlan Wright * Returns, 62629bd2886SAlan Wright * 0 = On success. 62729bd2886SAlan Wright * -1 = Failure to open /etc/mnttab file or to get ZFS dataset. 6286d57f833SAlan Wright */ 6296d57f833SAlan Wright int 6306d57f833SAlan Wright smb_getdataset(const char *path, char *dataset, size_t len) 6316d57f833SAlan Wright { 6326d57f833SAlan Wright char tmppath[MAXPATHLEN]; 6336d57f833SAlan Wright char *cp; 6346d57f833SAlan Wright FILE *fp; 6356d57f833SAlan Wright struct mnttab mnttab; 6366d57f833SAlan Wright struct mnttab mntpref; 6376d57f833SAlan Wright int rc = -1; 6386d57f833SAlan Wright 6396d57f833SAlan Wright if ((fp = fopen(MNTTAB, "r")) == NULL) 6406d57f833SAlan Wright return (-1); 6416d57f833SAlan Wright 6426d57f833SAlan Wright (void) memset(&mnttab, '\0', sizeof (mnttab)); 6436d57f833SAlan Wright (void) strlcpy(tmppath, path, MAXPATHLEN); 6446d57f833SAlan Wright cp = tmppath; 6456d57f833SAlan Wright 6466d57f833SAlan Wright while (*cp != '\0') { 6476d57f833SAlan Wright resetmnttab(fp); 6486d57f833SAlan Wright (void) memset(&mntpref, '\0', sizeof (mntpref)); 6496d57f833SAlan Wright mntpref.mnt_mountp = tmppath; 6506d57f833SAlan Wright 6516d57f833SAlan Wright if (getmntany(fp, &mnttab, &mntpref) == 0) { 65229bd2886SAlan Wright if (mnttab.mnt_fstype == NULL) 65329bd2886SAlan Wright break; 65429bd2886SAlan Wright 65529bd2886SAlan Wright if (strcmp(mnttab.mnt_fstype, "zfs") != 0) 65629bd2886SAlan Wright break; 6576d57f833SAlan Wright /* 6586d57f833SAlan Wright * Ensure that there are no leading slashes 6596d57f833SAlan Wright * (required for zfs_open). 6606d57f833SAlan Wright */ 6616d57f833SAlan Wright cp = mnttab.mnt_special; 6626d57f833SAlan Wright cp += strspn(cp, "/"); 6636d57f833SAlan Wright (void) strlcpy(dataset, cp, len); 6646d57f833SAlan Wright rc = 0; 6656d57f833SAlan Wright break; 6666d57f833SAlan Wright } 6676d57f833SAlan Wright 668fc724630SAlan Wright if (strcmp(tmppath, "/") == 0) 669fc724630SAlan Wright break; 670fc724630SAlan Wright 671fc724630SAlan Wright if ((cp = strrchr(tmppath, '/')) == NULL) 672fc724630SAlan Wright break; 673fc724630SAlan Wright 674fc724630SAlan Wright /* 675fc724630SAlan Wright * The path has multiple components. 676fc724630SAlan Wright * Remove the last component and try again. 677fc724630SAlan Wright */ 6786d57f833SAlan Wright *cp = '\0'; 6796d57f833SAlan Wright if (tmppath[0] == '\0') 6806d57f833SAlan Wright (void) strcpy(tmppath, "/"); 6816d57f833SAlan Wright 6826d57f833SAlan Wright cp = tmppath; 6836d57f833SAlan Wright } 6846d57f833SAlan Wright 6856d57f833SAlan Wright (void) fclose(fp); 6866d57f833SAlan Wright return (rc); 6876d57f833SAlan Wright } 68829bd2886SAlan Wright 68929bd2886SAlan Wright /* 6901fcced4cSJordan Brown * smb_dlopen 6911fcced4cSJordan Brown * 6921fcced4cSJordan Brown * Check to see if an interposer library exists. If it exists 6931fcced4cSJordan Brown * and reports a valid version number and key (UUID), return 6941fcced4cSJordan Brown * a handle to the library. Otherwise, return NULL. 6951fcced4cSJordan Brown */ 6961fcced4cSJordan Brown void * 6971fcced4cSJordan Brown smb_dlopen(void) 6981fcced4cSJordan Brown { 6991fcced4cSJordan Brown uuid_t uuid; 7001fcced4cSJordan Brown void *interposer_hdl; 7011fcced4cSJordan Brown typedef int (*smbex_versionfn_t)(smbex_version_t *); 7021fcced4cSJordan Brown smbex_versionfn_t getversion; 7031fcced4cSJordan Brown smbex_version_t *version; 7041fcced4cSJordan Brown 7051fcced4cSJordan Brown bzero(&uuid, sizeof (uuid_t)); 7061fcced4cSJordan Brown if (uuid_parse(SMBEX_KEY, uuid) < 0) 7071fcced4cSJordan Brown return (NULL); 7081fcced4cSJordan Brown 7091fcced4cSJordan Brown interposer_hdl = dlopen(SMB_LIB_ALT, RTLD_NOW | RTLD_LOCAL); 7101fcced4cSJordan Brown if (interposer_hdl == NULL) 7111fcced4cSJordan Brown return (NULL); 7121fcced4cSJordan Brown 7131fcced4cSJordan Brown bzero(&getversion, sizeof (smbex_versionfn_t)); 7141fcced4cSJordan Brown getversion = (smbex_versionfn_t)dlsym(interposer_hdl, 7151fcced4cSJordan Brown "smbex_get_version"); 7161fcced4cSJordan Brown if ((getversion == NULL) || 7171fcced4cSJordan Brown (version = malloc(sizeof (smbex_version_t))) == NULL) { 7181fcced4cSJordan Brown (void) dlclose(interposer_hdl); 7191fcced4cSJordan Brown return (NULL); 7201fcced4cSJordan Brown } 7211fcced4cSJordan Brown bzero(version, sizeof (smbex_version_t)); 7221fcced4cSJordan Brown 7231fcced4cSJordan Brown if ((getversion(version) != 0) || 7241fcced4cSJordan Brown (version->v_version != SMBEX_VERSION) || 7251fcced4cSJordan Brown (uuid_compare(version->v_uuid, uuid) != 0)) { 7261fcced4cSJordan Brown free(version); 7271fcced4cSJordan Brown (void) dlclose(interposer_hdl); 7281fcced4cSJordan Brown return (NULL); 7291fcced4cSJordan Brown } 7301fcced4cSJordan Brown 7311fcced4cSJordan Brown free(version); 7321fcced4cSJordan Brown return (interposer_hdl); 7331fcced4cSJordan Brown } 7341fcced4cSJordan Brown 7351fcced4cSJordan Brown /* 7361fcced4cSJordan Brown * smb_dlclose 7371fcced4cSJordan Brown * 7381fcced4cSJordan Brown * Closes handle to the interposed library. 7391fcced4cSJordan Brown */ 7401fcced4cSJordan Brown void 7411fcced4cSJordan Brown smb_dlclose(void *handle) 7421fcced4cSJordan Brown { 7431fcced4cSJordan Brown if (handle) 7441fcced4cSJordan Brown (void) dlclose(handle); 7451fcced4cSJordan Brown } 7461fcced4cSJordan Brown 7471fcced4cSJordan Brown /* 7489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * This function is a wrapper for getnameinfo() to look up a hostname given an 7499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * IP address. The hostname returned by this function is used for constructing 7509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * the service principal name field of KRB AP-REQs. Hence, it should be 7519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * converted to lowercase for RFC 4120 section 6.2.1 conformance. 75229bd2886SAlan Wright */ 75329bd2886SAlan Wright int 75429bd2886SAlan Wright smb_getnameinfo(smb_inaddr_t *ip, char *hostname, int hostlen, int flags) 75529bd2886SAlan Wright { 75629bd2886SAlan Wright socklen_t salen; 75729bd2886SAlan Wright struct sockaddr_in6 sin6; 75829bd2886SAlan Wright struct sockaddr_in sin; 75929bd2886SAlan Wright void *sp; 7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 76129bd2886SAlan Wright 76229bd2886SAlan Wright if (ip->a_family == AF_INET) { 76329bd2886SAlan Wright salen = sizeof (struct sockaddr_in); 76429bd2886SAlan Wright sin.sin_family = ip->a_family; 76529bd2886SAlan Wright sin.sin_port = 0; 76629bd2886SAlan Wright sin.sin_addr.s_addr = ip->a_ipv4; 76729bd2886SAlan Wright sp = &sin; 76829bd2886SAlan Wright } else { 76929bd2886SAlan Wright salen = sizeof (struct sockaddr_in6); 77029bd2886SAlan Wright sin6.sin6_family = ip->a_family; 77129bd2886SAlan Wright sin6.sin6_port = 0; 77229bd2886SAlan Wright (void) memcpy(&sin6.sin6_addr.s6_addr, &ip->a_ipv6, 77329bd2886SAlan Wright sizeof (sin6.sin6_addr.s6_addr)); 77429bd2886SAlan Wright sp = &sin6; 77529bd2886SAlan Wright } 7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = (getnameinfo((struct sockaddr *)sp, salen, 7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hostname, hostlen, NULL, 0, flags))) == 0) 7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_strlwr(hostname); 7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 78229bd2886SAlan Wright } 783fe1c642dSBill Krier 784fe1c642dSBill Krier /* 785fe1c642dSBill Krier * A share name is considered invalid if it contains control 786fe1c642dSBill Krier * characters or any of the following characters (MSDN 236388). 787fe1c642dSBill Krier * 788fe1c642dSBill Krier * " / \ [ ] : | < > + ; , ? * = 789fe1c642dSBill Krier */ 790fe1c642dSBill Krier uint32_t 791fe1c642dSBill Krier smb_name_validate_share(const char *sharename) 792fe1c642dSBill Krier { 793fe1c642dSBill Krier const char *invalid = "\"/\\[]:|<>+;,?*="; 794fe1c642dSBill Krier const char *p; 795fe1c642dSBill Krier 796fe1c642dSBill Krier if (sharename == NULL) 797fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 798fe1c642dSBill Krier 799fe1c642dSBill Krier if (strpbrk(sharename, invalid) != NULL) 800fe1c642dSBill Krier return (ERROR_INVALID_NAME); 801fe1c642dSBill Krier 802fe1c642dSBill Krier for (p = sharename; *p != '\0'; p++) { 803fe1c642dSBill Krier if (iscntrl(*p)) 804fe1c642dSBill Krier return (ERROR_INVALID_NAME); 805fe1c642dSBill Krier } 806fe1c642dSBill Krier 807fe1c642dSBill Krier return (ERROR_SUCCESS); 808fe1c642dSBill Krier } 809fe1c642dSBill Krier 810fe1c642dSBill Krier /* 811fe1c642dSBill Krier * User and group names are limited to 256 characters, cannot be terminated 812fe1c642dSBill Krier * by '.' and must not contain control characters or any of the following 813fe1c642dSBill Krier * characters. 814fe1c642dSBill Krier * 815fe1c642dSBill Krier * " / \ [ ] < > + ; , ? * = @ 816fe1c642dSBill Krier */ 817fe1c642dSBill Krier uint32_t 818fe1c642dSBill Krier smb_name_validate_account(const char *name) 819fe1c642dSBill Krier { 820fe1c642dSBill Krier const char *invalid = "\"/\\[]<>+;,?*=@"; 821fe1c642dSBill Krier const char *p; 822fe1c642dSBill Krier int len; 823fe1c642dSBill Krier 824fe1c642dSBill Krier if ((name == NULL) || (*name == '\0')) 825fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 826fe1c642dSBill Krier 827fe1c642dSBill Krier len = strlen(name); 828fe1c642dSBill Krier if ((len > MAXNAMELEN) || (name[len - 1] == '.')) 829fe1c642dSBill Krier return (ERROR_INVALID_NAME); 830fe1c642dSBill Krier 831fe1c642dSBill Krier if (strpbrk(name, invalid) != NULL) 832fe1c642dSBill Krier return (ERROR_INVALID_NAME); 833fe1c642dSBill Krier 834fe1c642dSBill Krier for (p = name; *p != '\0'; p++) { 835fe1c642dSBill Krier if (iscntrl(*p)) 836fe1c642dSBill Krier return (ERROR_INVALID_NAME); 837fe1c642dSBill Krier } 838fe1c642dSBill Krier 839fe1c642dSBill Krier return (ERROR_SUCCESS); 840fe1c642dSBill Krier } 841fe1c642dSBill Krier 842fe1c642dSBill Krier /* 843fe1c642dSBill Krier * Check a domain name for RFC 1035 and 1123 compliance. Domain names may 844fe1c642dSBill Krier * contain alphanumeric characters, hyphens and dots. The first and last 845fe1c642dSBill Krier * character of a label must be alphanumeric. Interior characters may be 846fe1c642dSBill Krier * alphanumeric or hypens. 847fe1c642dSBill Krier * 848fe1c642dSBill Krier * Domain names should not contain underscores but we allow them because 849fe1c642dSBill Krier * Windows names are often in non-compliance with this rule. 850fe1c642dSBill Krier */ 851fe1c642dSBill Krier uint32_t 852fe1c642dSBill Krier smb_name_validate_domain(const char *domain) 853fe1c642dSBill Krier { 854fe1c642dSBill Krier boolean_t new_label = B_TRUE; 855fe1c642dSBill Krier const char *p; 856fe1c642dSBill Krier char label_terminator; 857fe1c642dSBill Krier 858fe1c642dSBill Krier if (domain == NULL) 859fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 860fe1c642dSBill Krier 861fe1c642dSBill Krier if (*domain == '\0') 862fe1c642dSBill Krier return (ERROR_INVALID_NAME); 863fe1c642dSBill Krier 864fe1c642dSBill Krier label_terminator = *domain; 865fe1c642dSBill Krier 866fe1c642dSBill Krier for (p = domain; *p != '\0'; ++p) { 867fe1c642dSBill Krier if (new_label) { 868fe1c642dSBill Krier if (!isalnum(*p)) 869fe1c642dSBill Krier return (ERROR_INVALID_NAME); 870fe1c642dSBill Krier new_label = B_FALSE; 871fe1c642dSBill Krier label_terminator = *p; 872fe1c642dSBill Krier continue; 873fe1c642dSBill Krier } 874fe1c642dSBill Krier 875fe1c642dSBill Krier if (*p == '.') { 876fe1c642dSBill Krier if (!isalnum(label_terminator)) 877fe1c642dSBill Krier return (ERROR_INVALID_NAME); 878fe1c642dSBill Krier new_label = B_TRUE; 879fe1c642dSBill Krier label_terminator = *p; 880fe1c642dSBill Krier continue; 881fe1c642dSBill Krier } 882fe1c642dSBill Krier 883fe1c642dSBill Krier label_terminator = *p; 884fe1c642dSBill Krier 885fe1c642dSBill Krier if (isalnum(*p) || *p == '-' || *p == '_') 886fe1c642dSBill Krier continue; 887fe1c642dSBill Krier 888fe1c642dSBill Krier return (ERROR_INVALID_NAME); 889fe1c642dSBill Krier } 890fe1c642dSBill Krier 891fe1c642dSBill Krier if (!isalnum(label_terminator)) 892fe1c642dSBill Krier return (ERROR_INVALID_NAME); 893fe1c642dSBill Krier 894fe1c642dSBill Krier return (ERROR_SUCCESS); 895fe1c642dSBill Krier } 896fe1c642dSBill Krier 897fe1c642dSBill Krier /* 898fe1c642dSBill Krier * A NetBIOS domain name can contain letters (a-zA-Z), numbers (0-9) and 899fe1c642dSBill Krier * hyphens. 900fe1c642dSBill Krier * 901fe1c642dSBill Krier * It cannot: 902fe1c642dSBill Krier * - be blank or longer than 15 chracters 903fe1c642dSBill Krier * - contain all numbers 904fe1c642dSBill Krier * - be the same as the computer name 905fe1c642dSBill Krier */ 906fe1c642dSBill Krier uint32_t 907fe1c642dSBill Krier smb_name_validate_nbdomain(const char *name) 908fe1c642dSBill Krier { 909fe1c642dSBill Krier char netbiosname[NETBIOS_NAME_SZ]; 910fe1c642dSBill Krier const char *p; 911fe1c642dSBill Krier int len; 912fe1c642dSBill Krier 913fe1c642dSBill Krier if (name == NULL) 914fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 915fe1c642dSBill Krier 916fe1c642dSBill Krier len = strlen(name); 917fe1c642dSBill Krier if (len == 0 || len >= NETBIOS_NAME_SZ) 918fe1c642dSBill Krier return (ERROR_INVALID_NAME); 919fe1c642dSBill Krier 920fe1c642dSBill Krier if (strspn(name, "0123456789") == len) 921fe1c642dSBill Krier return (ERROR_INVALID_NAME); 922fe1c642dSBill Krier 923fe1c642dSBill Krier if (smb_getnetbiosname(netbiosname, NETBIOS_NAME_SZ) == 0) { 924fe1c642dSBill Krier if (smb_strcasecmp(name, netbiosname, 0) == 0) 925fe1c642dSBill Krier return (ERROR_INVALID_NAME); 926fe1c642dSBill Krier } 927fe1c642dSBill Krier 928fe1c642dSBill Krier for (p = name; *p != '\0'; ++p) { 929fe1c642dSBill Krier if (isalnum(*p) || *p == '-' || *p == '_') 930fe1c642dSBill Krier continue; 931fe1c642dSBill Krier 932fe1c642dSBill Krier return (ERROR_INVALID_NAME); 933fe1c642dSBill Krier } 934fe1c642dSBill Krier 935fe1c642dSBill Krier return (ERROR_SUCCESS); 936fe1c642dSBill Krier } 937fe1c642dSBill Krier 938fe1c642dSBill Krier /* 939fe1c642dSBill Krier * A workgroup name can contain 1 to 15 characters but cannot be the same 940fe1c642dSBill Krier * as the NetBIOS name. The name must begin with a letter or number. 941fe1c642dSBill Krier * 942fe1c642dSBill Krier * The name cannot consist entirely of spaces or dots, which is covered 943fe1c642dSBill Krier * by the requirement that the name must begin with an alphanumeric 944fe1c642dSBill Krier * character. 945fe1c642dSBill Krier * 946fe1c642dSBill Krier * The name must not contain control characters or any of the following 947fe1c642dSBill Krier * characters. 948fe1c642dSBill Krier * 949fe1c642dSBill Krier * " / \ [ ] : | < > + = ; , ? 950fe1c642dSBill Krier */ 951fe1c642dSBill Krier uint32_t 952fe1c642dSBill Krier smb_name_validate_workgroup(const char *workgroup) 953fe1c642dSBill Krier { 954fe1c642dSBill Krier char netbiosname[NETBIOS_NAME_SZ]; 955fe1c642dSBill Krier const char *invalid = "\"/\\[]:|<>+=;,?"; 956fe1c642dSBill Krier const char *p; 957fe1c642dSBill Krier 958fe1c642dSBill Krier if (workgroup == NULL) 959fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 960fe1c642dSBill Krier 961fe1c642dSBill Krier if (*workgroup == '\0' || (!isalnum(*workgroup))) 962fe1c642dSBill Krier return (ERROR_INVALID_NAME); 963fe1c642dSBill Krier 964fe1c642dSBill Krier if (strlen(workgroup) >= NETBIOS_NAME_SZ) 965fe1c642dSBill Krier return (ERROR_INVALID_NAME); 966fe1c642dSBill Krier 967fe1c642dSBill Krier if (smb_getnetbiosname(netbiosname, NETBIOS_NAME_SZ) == 0) { 968fe1c642dSBill Krier if (smb_strcasecmp(workgroup, netbiosname, 0) == 0) 969fe1c642dSBill Krier return (ERROR_INVALID_NAME); 970fe1c642dSBill Krier } 971fe1c642dSBill Krier 972fe1c642dSBill Krier if (strpbrk(workgroup, invalid) != NULL) 973fe1c642dSBill Krier return (ERROR_INVALID_NAME); 974fe1c642dSBill Krier 975fe1c642dSBill Krier for (p = workgroup; *p != '\0'; p++) { 976fe1c642dSBill Krier if (iscntrl(*p)) 977fe1c642dSBill Krier return (ERROR_INVALID_NAME); 978fe1c642dSBill Krier } 979fe1c642dSBill Krier 980fe1c642dSBill Krier return (ERROR_SUCCESS); 981fe1c642dSBill Krier } 982fe1c642dSBill Krier 983fe1c642dSBill Krier /* 9849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Check for invalid characters in the given path. The list of invalid 9859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * characters includes control characters and the following: 9869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 9879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * " / \ [ ] : | < > + ; , ? * = 9889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 9899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Since this is checking a path not each component, '/' is accepted 9909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * as separator not an invalid character, except as the first character 9919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * since this is supposed to be a relative path. 9929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 9939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t 9949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_name_validate_rpath(const char *relpath) 9959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 9969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *invalid = "\"\\[]:|<>+;,?*="; 9979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *cp; 9989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 9999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((relpath == NULL) || (*relpath == '\0') || (*relpath == '/')) 10009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_INVALID_NAME); 10019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (strpbrk(relpath, invalid)) 10039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_INVALID_NAME); 10049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States for (cp = (char *)relpath; *cp != '\0'; cp++) { 10069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (iscntrl(*cp)) 10079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_INVALID_NAME); 10089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 10099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_SUCCESS); 10119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 10129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 1014fe1c642dSBill Krier * Parse a string to obtain the account and domain names as separate strings. 1015fe1c642dSBill Krier * 1016fe1c642dSBill Krier * Names containing a backslash ('\') are known as qualified or composite 1017fe1c642dSBill Krier * names. The string preceding the backslash should be the domain name 1018fe1c642dSBill Krier * and the string following the slash should be a name within that domain. 1019fe1c642dSBill Krier * 1020fe1c642dSBill Krier * Names that do not contain a backslash are known as isolated names. 1021fe1c642dSBill Krier * An isolated name may be a single label, such as john, or may be in 1022fe1c642dSBill Krier * user principal name (UPN) form, such as john@example.com. 1023fe1c642dSBill Krier * 1024fe1c642dSBill Krier * domain\name 1025fe1c642dSBill Krier * domain/name 1026fe1c642dSBill Krier * name 1027fe1c642dSBill Krier * name@domain 1028fe1c642dSBill Krier * 1029fe1c642dSBill Krier * If we encounter any of the forms above in arg, the @, / or \ separator 1030fe1c642dSBill Krier * is replaced by \0 and the name and domain pointers are set to point to 1031fe1c642dSBill Krier * the appropriate components in arg. Otherwise, name and domain pointers 1032fe1c642dSBill Krier * will be set to NULL. 1033fe1c642dSBill Krier */ 1034fe1c642dSBill Krier void 1035fe1c642dSBill Krier smb_name_parse(char *arg, char **account, char **domain) 1036fe1c642dSBill Krier { 1037fe1c642dSBill Krier char *p; 1038fe1c642dSBill Krier 1039fe1c642dSBill Krier *account = NULL; 1040fe1c642dSBill Krier *domain = NULL; 1041fe1c642dSBill Krier 1042fe1c642dSBill Krier if ((p = strpbrk(arg, "/\\@")) != NULL) { 1043fe1c642dSBill Krier if (*p == '@') { 1044fe1c642dSBill Krier *p = '\0'; 1045fe1c642dSBill Krier ++p; 1046fe1c642dSBill Krier *domain = p; 1047fe1c642dSBill Krier *account = arg; 1048fe1c642dSBill Krier } else { 1049fe1c642dSBill Krier *p = '\0'; 1050fe1c642dSBill Krier ++p; 1051fe1c642dSBill Krier *account = p; 1052fe1c642dSBill Krier *domain = arg; 1053fe1c642dSBill Krier } 1054fe1c642dSBill Krier } 1055fe1c642dSBill Krier } 1056148c5f43SAlan Wright 1057148c5f43SAlan Wright /* 1058148c5f43SAlan Wright * The txid is an arbitrary transaction. A new txid is returned on each call. 1059148c5f43SAlan Wright * 1060148c5f43SAlan Wright * 0 or -1 are not assigned so that they can be used to detect 1061148c5f43SAlan Wright * invalid conditions. 1062148c5f43SAlan Wright */ 1063148c5f43SAlan Wright uint32_t 1064148c5f43SAlan Wright smb_get_txid(void) 1065148c5f43SAlan Wright { 1066148c5f43SAlan Wright static mutex_t txmutex; 1067148c5f43SAlan Wright static uint32_t txid; 1068148c5f43SAlan Wright uint32_t txid_ret; 1069148c5f43SAlan Wright 1070148c5f43SAlan Wright (void) mutex_lock(&txmutex); 1071148c5f43SAlan Wright 1072148c5f43SAlan Wright if (txid == 0) 1073148c5f43SAlan Wright txid = time(NULL); 1074148c5f43SAlan Wright 1075148c5f43SAlan Wright do { 1076148c5f43SAlan Wright ++txid; 1077148c5f43SAlan Wright } while (txid == 0 || txid == (uint32_t)-1); 1078148c5f43SAlan Wright 1079148c5f43SAlan Wright txid_ret = txid; 1080148c5f43SAlan Wright (void) mutex_unlock(&txmutex); 1081148c5f43SAlan Wright 1082148c5f43SAlan Wright return (txid_ret); 1083148c5f43SAlan Wright } 1084