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. 232807a6ecSYuri Pankov * Copyright 2011 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 52148c5f43SAlan Wright #define SMB_TIMEBUF_SZ 16 53148c5f43SAlan Wright #define SMB_TRACEBUF_SZ 200 54148c5f43SAlan Wright 55148c5f43SAlan Wright #define SMB_LOG_FILE_FMT "/var/smb/%s_log.txt" 56148c5f43SAlan Wright 57148c5f43SAlan Wright typedef struct smb_log_pri { 58148c5f43SAlan Wright char *lp_name; 59148c5f43SAlan Wright int lp_value; 60148c5f43SAlan Wright } smb_log_pri_t; 61148c5f43SAlan Wright 62148c5f43SAlan Wright static smb_log_pri_t smb_log_pri[] = { 63148c5f43SAlan Wright "panic", LOG_EMERG, 64148c5f43SAlan Wright "emerg", LOG_EMERG, 65148c5f43SAlan Wright "alert", LOG_ALERT, 66148c5f43SAlan Wright "crit", LOG_CRIT, 67148c5f43SAlan Wright "error", LOG_ERR, 68148c5f43SAlan Wright "err", LOG_ERR, 69148c5f43SAlan Wright "warn", LOG_WARNING, 70148c5f43SAlan Wright "warning", LOG_WARNING, 71148c5f43SAlan Wright "notice", LOG_NOTICE, 72148c5f43SAlan Wright "info", LOG_INFO, 73148c5f43SAlan Wright "debug", LOG_DEBUG 74148c5f43SAlan Wright }; 75148c5f43SAlan Wright 76148c5f43SAlan Wright static void smb_log_trace(int, const char *); 77148c5f43SAlan Wright static smb_log_t *smb_log_get(smb_log_hdl_t); 78148c5f43SAlan Wright static void smb_log_dump(smb_log_t *); 79148c5f43SAlan Wright 80b89a8333Snatalie li - Sun Microsystems - Irvine United States static boolean_t smb_netgroup_match(struct nd_hostservlist *, char *, int); 81b89a8333Snatalie li - Sun Microsystems - Irvine United States 82*9b241b4eSYuri Pankov extern int __multi_innetgr(); 83b89a8333Snatalie li - Sun Microsystems - Irvine United States extern int __netdir_getbyaddr_nosrv(struct netconfig *, 84b89a8333Snatalie li - Sun Microsystems - Irvine United States struct nd_hostservlist **, struct netbuf *); 85da6c28aaSamw 86148c5f43SAlan Wright static smb_loglist_t smb_loglist; 87148c5f43SAlan Wright 88da6c28aaSamw #define C2H(c) "0123456789ABCDEF"[(c)] 89da6c28aaSamw #define H2C(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \ 90da6c28aaSamw ((c) >= 'a' && (c) <= 'f') ? ((c) - 'a' + 10) : \ 91da6c28aaSamw ((c) >= 'A' && (c) <= 'F') ? ((c) - 'A' + 10) : \ 92da6c28aaSamw '\0') 93da6c28aaSamw #define DEFAULT_SBOX_SIZE 256 94da6c28aaSamw 95da6c28aaSamw /* 96da6c28aaSamw * 97da6c28aaSamw * hexdump 98da6c28aaSamw * 99da6c28aaSamw * Simple hex dump display function. Displays nbytes of buffer in hex and 100da6c28aaSamw * printable format. Non-printing characters are shown as '.'. It is safe 101da6c28aaSamw * to pass a null pointer. Each line begins with the offset. If nbytes is 102da6c28aaSamw * 0, the line will be blank except for the offset. Example output: 103da6c28aaSamw * 104da6c28aaSamw * 00000000 54 68 69 73 20 69 73 20 61 20 70 72 6F 67 72 61 This is a progra 105da6c28aaSamw * 00000010 6D 20 74 65 73 74 2E 00 m test.. 106da6c28aaSamw * 107da6c28aaSamw */ 108da6c28aaSamw void 109dc20a302Sas hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start) 110da6c28aaSamw { 111da6c28aaSamw static char *hex = "0123456789ABCDEF"; 112da6c28aaSamw int i, count; 113da6c28aaSamw int offset; 114da6c28aaSamw unsigned char *p; 115da6c28aaSamw char ascbuf[64]; 116da6c28aaSamw char hexbuf[64]; 117da6c28aaSamw char *ap = ascbuf; 118da6c28aaSamw char *hp = hexbuf; 119da6c28aaSamw 120dc20a302Sas if ((p = buffer) == NULL) 121da6c28aaSamw return; 122da6c28aaSamw 123da6c28aaSamw offset = *start; 124da6c28aaSamw 125da6c28aaSamw *ap = '\0'; 126da6c28aaSamw *hp = '\0'; 127da6c28aaSamw count = 0; 128da6c28aaSamw 129da6c28aaSamw for (i = 0; i < nbytes; ++i) { 130da6c28aaSamw if (i && (i % 16) == 0) { 131dc20a302Sas smb_tracef("%06X %s %s", offset, hexbuf, ascbuf); 132da6c28aaSamw ap = ascbuf; 133da6c28aaSamw hp = hexbuf; 134da6c28aaSamw count = 0; 135da6c28aaSamw offset += 16; 136da6c28aaSamw } 137da6c28aaSamw 138da6c28aaSamw ap += sprintf(ap, "%c", 139da6c28aaSamw (*p >= 0x20 && *p < 0x7F) ? *p : '.'); 140da6c28aaSamw hp += sprintf(hp, " %c%c", 141da6c28aaSamw hex[(*p >> 4) & 0x0F], hex[(*p & 0x0F)]); 142da6c28aaSamw ++p; 143da6c28aaSamw ++count; 144da6c28aaSamw } 145da6c28aaSamw 146da6c28aaSamw if (count) { 147dc20a302Sas smb_tracef("%06X %-48s %s", offset, hexbuf, ascbuf); 148da6c28aaSamw offset += count; 149da6c28aaSamw } 150da6c28aaSamw 151da6c28aaSamw *start = offset; 152da6c28aaSamw } 153da6c28aaSamw 154da6c28aaSamw void 155da6c28aaSamw hexdump(unsigned char *buffer, int nbytes) 156da6c28aaSamw { 157da6c28aaSamw unsigned long start = 0; 158da6c28aaSamw 159dc20a302Sas hexdump_offset(buffer, nbytes, &start); 160da6c28aaSamw } 161da6c28aaSamw 162da6c28aaSamw /* 163da6c28aaSamw * bintohex 164da6c28aaSamw * 165da6c28aaSamw * Converts the given binary data (srcbuf) to 166da6c28aaSamw * its equivalent hex chars (hexbuf). 167da6c28aaSamw * 168da6c28aaSamw * hexlen should be at least twice as srclen. 169da6c28aaSamw * if hexbuf is not big enough returns 0. 170da6c28aaSamw * otherwise returns number of valid chars in 171da6c28aaSamw * hexbuf which is srclen * 2. 172da6c28aaSamw */ 173da6c28aaSamw size_t 174da6c28aaSamw bintohex(const char *srcbuf, size_t srclen, 175da6c28aaSamw char *hexbuf, size_t hexlen) 176da6c28aaSamw { 177da6c28aaSamw size_t outlen; 178da6c28aaSamw char c; 179da6c28aaSamw 180da6c28aaSamw outlen = srclen << 1; 181da6c28aaSamw 182da6c28aaSamw if (hexlen < outlen) 183da6c28aaSamw return (0); 184da6c28aaSamw 185da6c28aaSamw while (srclen-- > 0) { 186da6c28aaSamw c = *srcbuf++; 187da6c28aaSamw *hexbuf++ = C2H(c & 0xF); 188da6c28aaSamw *hexbuf++ = C2H((c >> 4) & 0xF); 189da6c28aaSamw } 190da6c28aaSamw 191da6c28aaSamw return (outlen); 192da6c28aaSamw } 193da6c28aaSamw 194da6c28aaSamw /* 195da6c28aaSamw * hextobin 196da6c28aaSamw * 197da6c28aaSamw * Converts hex to binary. 198da6c28aaSamw * 199da6c28aaSamw * Assuming hexbuf only contains hex digits (chars) 200da6c28aaSamw * this function convert every two bytes of hexbuf 201da6c28aaSamw * to one byte and put it in dstbuf. 202da6c28aaSamw * 203da6c28aaSamw * hexlen should be an even number. 204da6c28aaSamw * dstlen should be at least half of hexlen. 205da6c28aaSamw * 206da6c28aaSamw * Returns 0 if sizes are not correct, otherwise 207da6c28aaSamw * returns the number of converted bytes in dstbuf 208da6c28aaSamw * which is half of hexlen. 209da6c28aaSamw */ 210da6c28aaSamw size_t 211da6c28aaSamw hextobin(const char *hexbuf, size_t hexlen, 212da6c28aaSamw char *dstbuf, size_t dstlen) 213da6c28aaSamw { 214da6c28aaSamw size_t outlen; 215da6c28aaSamw 216da6c28aaSamw if ((hexlen % 2) != 0) 217da6c28aaSamw return (0); 218da6c28aaSamw 219da6c28aaSamw outlen = hexlen >> 1; 220da6c28aaSamw if (dstlen < outlen) 221da6c28aaSamw return (0); 222da6c28aaSamw 223da6c28aaSamw while (hexlen > 0) { 224da6c28aaSamw *dstbuf = H2C(*hexbuf) & 0x0F; 225da6c28aaSamw hexbuf++; 226da6c28aaSamw *dstbuf++ |= (H2C(*hexbuf) << 4) & 0xF0; 227da6c28aaSamw hexbuf++; 228da6c28aaSamw 229da6c28aaSamw hexlen -= 2; 230da6c28aaSamw } 231da6c28aaSamw 232da6c28aaSamw return (outlen); 233da6c28aaSamw } 234da6c28aaSamw 2358d7e4166Sjose borrego /* 2368d7e4166Sjose borrego * Trim leading and trailing characters in the set defined by class 2378d7e4166Sjose borrego * from a buffer containing a null-terminated string. 2388d7e4166Sjose borrego * For example, if the input buffer contained "ABtext23" and class 2398d7e4166Sjose borrego * contains "ABC123", the buffer will contain "text" on return. 2408d7e4166Sjose borrego * 2418d7e4166Sjose borrego * This function modifies the contents of buf in place and returns 2428d7e4166Sjose borrego * a pointer to buf. 2438d7e4166Sjose borrego */ 2448d7e4166Sjose borrego char * 2458d7e4166Sjose borrego strtrim(char *buf, const char *class) 2468d7e4166Sjose borrego { 2478d7e4166Sjose borrego char *p = buf; 2488d7e4166Sjose borrego char *q = buf; 2498d7e4166Sjose borrego 2508d7e4166Sjose borrego if (buf == NULL) 2518d7e4166Sjose borrego return (NULL); 2528d7e4166Sjose borrego 2538d7e4166Sjose borrego p += strspn(p, class); 2548d7e4166Sjose borrego 2558d7e4166Sjose borrego if (p != buf) { 2568d7e4166Sjose borrego while ((*q = *p++) != '\0') 2578d7e4166Sjose borrego ++q; 2588d7e4166Sjose borrego } 2598d7e4166Sjose borrego 2608d7e4166Sjose borrego while (q != buf) { 2618d7e4166Sjose borrego --q; 2628d7e4166Sjose borrego if (strspn(q, class) == 0) 2638d7e4166Sjose borrego return (buf); 2648d7e4166Sjose borrego *q = '\0'; 2658d7e4166Sjose borrego } 2668d7e4166Sjose borrego 2678d7e4166Sjose borrego return (buf); 2688d7e4166Sjose borrego } 2698d7e4166Sjose borrego 2708d7e4166Sjose borrego /* 2718d7e4166Sjose borrego * Strip the characters in the set defined by class from a buffer 2728d7e4166Sjose borrego * containing a null-terminated string. 2738d7e4166Sjose borrego * For example, if the input buffer contained "XYA 1textZ string3" 2748d7e4166Sjose borrego * and class contains "123XYZ", the buffer will contain "A text string" 2758d7e4166Sjose borrego * on return. 2768d7e4166Sjose borrego * 2778d7e4166Sjose borrego * This function modifies the contents of buf in place and returns 2788d7e4166Sjose borrego * a pointer to buf. 2798d7e4166Sjose borrego */ 2808d7e4166Sjose borrego char * 2818d7e4166Sjose borrego strstrip(char *buf, const char *class) 2828d7e4166Sjose borrego { 2838d7e4166Sjose borrego char *p = buf; 2848d7e4166Sjose borrego char *q = buf; 2858d7e4166Sjose borrego 2868d7e4166Sjose borrego if (buf == NULL) 2878d7e4166Sjose borrego return (NULL); 2888d7e4166Sjose borrego 2898d7e4166Sjose borrego while (*p) { 2908d7e4166Sjose borrego p += strspn(p, class); 2918d7e4166Sjose borrego *q++ = *p++; 2928d7e4166Sjose borrego } 2938d7e4166Sjose borrego 2948d7e4166Sjose borrego *q = '\0'; 2958d7e4166Sjose borrego return (buf); 2968d7e4166Sjose borrego } 2978d7e4166Sjose borrego 298da6c28aaSamw /* 299da6c28aaSamw * trim_whitespace 300da6c28aaSamw * 301da6c28aaSamw * Trim leading and trailing whitespace chars (as defined by isspace) 302da6c28aaSamw * from a buffer. Example; if the input buffer contained " text ", 303da6c28aaSamw * it will contain "text", when we return. We assume that the buffer 304da6c28aaSamw * contains a null terminated string. A pointer to the buffer is 305da6c28aaSamw * returned. 306da6c28aaSamw */ 307da6c28aaSamw char * 308da6c28aaSamw trim_whitespace(char *buf) 309da6c28aaSamw { 310da6c28aaSamw char *p = buf; 311da6c28aaSamw char *q = buf; 312da6c28aaSamw 313dc20a302Sas if (buf == NULL) 314dc20a302Sas return (NULL); 315da6c28aaSamw 316da6c28aaSamw while (*p && isspace(*p)) 317da6c28aaSamw ++p; 318da6c28aaSamw 319da6c28aaSamw while ((*q = *p++) != 0) 320da6c28aaSamw ++q; 321da6c28aaSamw 322da6c28aaSamw if (q != buf) { 323da6c28aaSamw while ((--q, isspace(*q)) != 0) 324da6c28aaSamw *q = '\0'; 325da6c28aaSamw } 326da6c28aaSamw 327da6c28aaSamw return (buf); 328da6c28aaSamw } 329da6c28aaSamw 330da6c28aaSamw /* 331da6c28aaSamw * randomize 332da6c28aaSamw * 333da6c28aaSamw * Randomize the contents of the specified buffer. 334da6c28aaSamw */ 335da6c28aaSamw void 336da6c28aaSamw randomize(char *data, unsigned len) 337da6c28aaSamw { 338da6c28aaSamw unsigned dwlen = len / 4; 339da6c28aaSamw unsigned remlen = len % 4; 340da6c28aaSamw unsigned tmp; 341da6c28aaSamw unsigned i; /*LINTED E_BAD_PTR_CAST_ALIGN*/ 342da6c28aaSamw unsigned *p = (unsigned *)data; 343da6c28aaSamw 344da6c28aaSamw for (i = 0; i < dwlen; ++i) 345da6c28aaSamw *p++ = random(); 346da6c28aaSamw 347da6c28aaSamw if (remlen) { 348da6c28aaSamw tmp = random(); 349da6c28aaSamw (void) memcpy(p, &tmp, remlen); 350da6c28aaSamw } 351da6c28aaSamw } 352da6c28aaSamw 353da6c28aaSamw /* 354da6c28aaSamw * This is the hash mechanism used to encrypt passwords for commands like 355da6c28aaSamw * SamrSetUserInformation. It uses a 256 byte s-box. 356da6c28aaSamw */ 357da6c28aaSamw void 358da6c28aaSamw rand_hash( 359da6c28aaSamw unsigned char *data, 360da6c28aaSamw size_t datalen, 361da6c28aaSamw unsigned char *key, 362da6c28aaSamw size_t keylen) 363da6c28aaSamw { 364da6c28aaSamw unsigned char sbox[DEFAULT_SBOX_SIZE]; 365da6c28aaSamw unsigned char tmp; 366da6c28aaSamw unsigned char index_i = 0; 367da6c28aaSamw unsigned char index_j = 0; 368da6c28aaSamw unsigned char j = 0; 369da6c28aaSamw int i; 370da6c28aaSamw 371da6c28aaSamw for (i = 0; i < DEFAULT_SBOX_SIZE; ++i) 372da6c28aaSamw sbox[i] = (unsigned char)i; 373da6c28aaSamw 374da6c28aaSamw for (i = 0; i < DEFAULT_SBOX_SIZE; ++i) { 375da6c28aaSamw j += (sbox[i] + key[i % keylen]); 376da6c28aaSamw 377da6c28aaSamw tmp = sbox[i]; 378da6c28aaSamw sbox[i] = sbox[j]; 379da6c28aaSamw sbox[j] = tmp; 380da6c28aaSamw } 381da6c28aaSamw 382da6c28aaSamw for (i = 0; i < datalen; ++i) { 383da6c28aaSamw index_i++; 384da6c28aaSamw index_j += sbox[index_i]; 385da6c28aaSamw 386da6c28aaSamw tmp = sbox[index_i]; 387da6c28aaSamw sbox[index_i] = sbox[index_j]; 388da6c28aaSamw sbox[index_j] = tmp; 389da6c28aaSamw 390da6c28aaSamw tmp = sbox[index_i] + sbox[index_j]; 391da6c28aaSamw data[i] = data[i] ^ sbox[tmp]; 392da6c28aaSamw } 393da6c28aaSamw } 394b89a8333Snatalie li - Sun Microsystems - Irvine United States 395b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 396b89a8333Snatalie li - Sun Microsystems - Irvine United States * smb_chk_hostaccess 397b89a8333Snatalie li - Sun Microsystems - Irvine United States * 398148c5f43SAlan Wright * Determines whether the specified host is in the given access list. 399148c5f43SAlan Wright * 400b89a8333Snatalie li - Sun Microsystems - Irvine United States * We match on aliases of the hostname as well as on the canonical name. 401b89a8333Snatalie li - Sun Microsystems - Irvine United States * Names in the access list may be either hosts or netgroups; they're 402b89a8333Snatalie li - Sun Microsystems - Irvine United States * not distinguished syntactically. We check for hosts first because 403b89a8333Snatalie li - Sun Microsystems - Irvine United States * it's cheaper (just M*N strcmp()s), then try netgroups. 404b89a8333Snatalie li - Sun Microsystems - Irvine United States * 405b89a8333Snatalie li - Sun Microsystems - Irvine United States * Function returns: 406148c5f43SAlan Wright * -1 for "all" (list is empty "" or "*") 407148c5f43SAlan Wright * 0 not found (host is not in the list or list is NULL) 408b89a8333Snatalie li - Sun Microsystems - Irvine United States * 1 found 4097f667e74Sjose borrego * 410b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 411b89a8333Snatalie li - Sun Microsystems - Irvine United States int 4127f667e74Sjose borrego smb_chk_hostaccess(smb_inaddr_t *ipaddr, char *access_list) 413b89a8333Snatalie li - Sun Microsystems - Irvine United States { 414*9b241b4eSYuri Pankov char addr[INET_ADDRSTRLEN]; 415*9b241b4eSYuri Pankov char buff[256]; 416*9b241b4eSYuri Pankov char *cstr = access_list, *gr = access_list; 417b89a8333Snatalie li - Sun Microsystems - Irvine United States char *host; 418*9b241b4eSYuri Pankov int clres; 419b89a8333Snatalie li - Sun Microsystems - Irvine United States int i; 420*9b241b4eSYuri Pankov int nentries = 0; 421*9b241b4eSYuri Pankov int off; 422b89a8333Snatalie li - Sun Microsystems - Irvine United States int response; 423*9b241b4eSYuri Pankov int sbr = 0; 424b89a8333Snatalie li - Sun Microsystems - Irvine United States struct nd_hostservlist *clnames; 425b89a8333Snatalie li - Sun Microsystems - Irvine United States struct in_addr inaddr; 426b89a8333Snatalie li - Sun Microsystems - Irvine United States struct sockaddr_in sa; 427*9b241b4eSYuri Pankov struct sockaddr_in6 sa6; 428b89a8333Snatalie li - Sun Microsystems - Irvine United States struct netbuf buf; 429b89a8333Snatalie li - Sun Microsystems - Irvine United States struct netconfig *config; 430*9b241b4eSYuri Pankov struct netent n, *np; 431b89a8333Snatalie li - Sun Microsystems - Irvine United States 432148c5f43SAlan Wright if (access_list == NULL) 433148c5f43SAlan Wright return (0); 4347f667e74Sjose borrego 435*9b241b4eSYuri Pankov /* If access list is empty or "*" - then it's "all" */ 436148c5f43SAlan Wright if (*access_list == '\0' || strcmp(access_list, "*") == 0) 437b89a8333Snatalie li - Sun Microsystems - Irvine United States return (-1); 438b89a8333Snatalie li - Sun Microsystems - Irvine United States 439*9b241b4eSYuri Pankov switch (ipaddr->a_family) { 440*9b241b4eSYuri Pankov case AF_INET: 441*9b241b4eSYuri Pankov inaddr.s_addr = ipaddr->a_ipv4; 442*9b241b4eSYuri Pankov sa.sin_family = AF_INET; 443*9b241b4eSYuri Pankov sa.sin_port = 0; 444*9b241b4eSYuri Pankov sa.sin_addr = inaddr; 445*9b241b4eSYuri Pankov buf.len = buf.maxlen = sizeof (sa); 446*9b241b4eSYuri Pankov buf.buf = (char *)&sa; 447*9b241b4eSYuri Pankov config = getnetconfigent("tcp"); 448*9b241b4eSYuri Pankov break; 449*9b241b4eSYuri Pankov case AF_INET6: 450*9b241b4eSYuri Pankov sa6.sin6_family = AF_INET6; 451*9b241b4eSYuri Pankov sa6.sin6_port = 0; 452*9b241b4eSYuri Pankov sa6.sin6_addr = ipaddr->a_ipv6; 453*9b241b4eSYuri Pankov buf.len = buf.maxlen = sizeof (sa6); 454*9b241b4eSYuri Pankov buf.buf = (char *)&sa6; 455*9b241b4eSYuri Pankov config = getnetconfigent("tcp6"); 456*9b241b4eSYuri Pankov break; 457*9b241b4eSYuri Pankov default: 458*9b241b4eSYuri Pankov return (1); 459*9b241b4eSYuri Pankov } 460b89a8333Snatalie li - Sun Microsystems - Irvine United States 461b89a8333Snatalie li - Sun Microsystems - Irvine United States if (config == NULL) 462b89a8333Snatalie li - Sun Microsystems - Irvine United States return (1); 463b89a8333Snatalie li - Sun Microsystems - Irvine United States 464*9b241b4eSYuri Pankov /* Try to lookup client hostname */ 4652807a6ecSYuri Pankov clres = __netdir_getbyaddr_nosrv(config, &clnames, &buf); 466b89a8333Snatalie li - Sun Microsystems - Irvine United States freenetconfigent(config); 467b89a8333Snatalie li - Sun Microsystems - Irvine United States 468*9b241b4eSYuri Pankov for (;;) { 469*9b241b4eSYuri Pankov if ((cstr = strpbrk(cstr, "[]:")) != NULL) { 470*9b241b4eSYuri Pankov switch (*cstr) { 471*9b241b4eSYuri Pankov case '[': 472*9b241b4eSYuri Pankov case ']': 473*9b241b4eSYuri Pankov sbr = !sbr; 474*9b241b4eSYuri Pankov cstr++; 475*9b241b4eSYuri Pankov continue; 476*9b241b4eSYuri Pankov case ':': 477*9b241b4eSYuri Pankov if (sbr) { 478*9b241b4eSYuri Pankov cstr++; 479*9b241b4eSYuri Pankov continue; 480*9b241b4eSYuri Pankov } 481*9b241b4eSYuri Pankov *cstr = '\0'; 482*9b241b4eSYuri Pankov } 483*9b241b4eSYuri Pankov } 484b89a8333Snatalie li - Sun Microsystems - Irvine United States 485b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 486*9b241b4eSYuri Pankov * If the list name has a '-' prepended then a match of 487*9b241b4eSYuri Pankov * the following name implies failure instead of success. 488b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 489b89a8333Snatalie li - Sun Microsystems - Irvine United States if (*gr == '-') { 490b89a8333Snatalie li - Sun Microsystems - Irvine United States response = 0; 491b89a8333Snatalie li - Sun Microsystems - Irvine United States gr++; 492b89a8333Snatalie li - Sun Microsystems - Irvine United States } else { 493b89a8333Snatalie li - Sun Microsystems - Irvine United States response = 1; 494b89a8333Snatalie li - Sun Microsystems - Irvine United States } 495b89a8333Snatalie li - Sun Microsystems - Irvine United States 496b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 497*9b241b4eSYuri Pankov * First check if we have '@' entry, as it doesn't 498*9b241b4eSYuri Pankov * require client hostname. 4992807a6ecSYuri Pankov */ 500*9b241b4eSYuri Pankov if (*gr == '@') { 501*9b241b4eSYuri Pankov gr++; 502*9b241b4eSYuri Pankov 503*9b241b4eSYuri Pankov if (!isdigit(*gr) && *gr != '[') { 504*9b241b4eSYuri Pankov /* Netname support */ 505*9b241b4eSYuri Pankov if ((np = getnetbyname_r(gr, &n, buff, 506*9b241b4eSYuri Pankov sizeof (buff))) != NULL && 507*9b241b4eSYuri Pankov np->n_net != 0) { 508*9b241b4eSYuri Pankov while ((np->n_net & 0xFF000000u) == 0) 509*9b241b4eSYuri Pankov np->n_net <<= 8; 510*9b241b4eSYuri Pankov np->n_net = htonl(np->n_net); 511*9b241b4eSYuri Pankov if (inet_ntop(AF_INET, &np->n_net, addr, 512*9b241b4eSYuri Pankov INET_ADDRSTRLEN) == NULL) 513*9b241b4eSYuri Pankov break; 514*9b241b4eSYuri Pankov if (inet_matchaddr(buf.buf, addr)) 515*9b241b4eSYuri Pankov return (response); 516*9b241b4eSYuri Pankov } 517*9b241b4eSYuri Pankov } else { 518*9b241b4eSYuri Pankov if (inet_matchaddr(buf.buf, gr)) 519*9b241b4eSYuri Pankov return (response); 520*9b241b4eSYuri Pankov } 521*9b241b4eSYuri Pankov 522*9b241b4eSYuri Pankov if (cstr == NULL) 523*9b241b4eSYuri Pankov break; 524*9b241b4eSYuri Pankov 525*9b241b4eSYuri Pankov gr = ++cstr; 526*9b241b4eSYuri Pankov 527*9b241b4eSYuri Pankov continue; 528*9b241b4eSYuri Pankov } 529*9b241b4eSYuri Pankov 5302807a6ecSYuri Pankov /* 5312807a6ecSYuri Pankov * No other checks can be performed if client address 5322807a6ecSYuri Pankov * can't be resolved. 5332807a6ecSYuri Pankov */ 534*9b241b4eSYuri Pankov if (clres) { 535*9b241b4eSYuri Pankov if (cstr == NULL) 536*9b241b4eSYuri Pankov break; 537*9b241b4eSYuri Pankov 538*9b241b4eSYuri Pankov gr = ++cstr; 539*9b241b4eSYuri Pankov 5402807a6ecSYuri Pankov continue; 541*9b241b4eSYuri Pankov } 542*9b241b4eSYuri Pankov 543*9b241b4eSYuri Pankov /* Otherwise loop through all client hostname aliases */ 544b89a8333Snatalie li - Sun Microsystems - Irvine United States for (i = 0; i < clnames->h_cnt; i++) { 545b89a8333Snatalie li - Sun Microsystems - Irvine United States host = clnames->h_hostservs[i].h_host; 546b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 547b89a8333Snatalie li - Sun Microsystems - Irvine United States * If the list name begins with a dot then 548b89a8333Snatalie li - Sun Microsystems - Irvine United States * do a domain name suffix comparison. 549b89a8333Snatalie li - Sun Microsystems - Irvine United States * A single dot matches any name with no 550b89a8333Snatalie li - Sun Microsystems - Irvine United States * suffix. 551b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 552b89a8333Snatalie li - Sun Microsystems - Irvine United States if (*gr == '.') { 553*9b241b4eSYuri Pankov if (*(gr + 1) == '\0') { 554b89a8333Snatalie li - Sun Microsystems - Irvine United States if (strchr(host, '.') == NULL) 555b89a8333Snatalie li - Sun Microsystems - Irvine United States return (response); 556b89a8333Snatalie li - Sun Microsystems - Irvine United States } else { 557b89a8333Snatalie li - Sun Microsystems - Irvine United States off = strlen(host) - strlen(gr); 558b89a8333Snatalie li - Sun Microsystems - Irvine United States if (off > 0 && 559b89a8333Snatalie li - Sun Microsystems - Irvine United States strcasecmp(host + off, gr) == 0) { 560b89a8333Snatalie li - Sun Microsystems - Irvine United States return (response); 561b89a8333Snatalie li - Sun Microsystems - Irvine United States } 562b89a8333Snatalie li - Sun Microsystems - Irvine United States } 563b89a8333Snatalie li - Sun Microsystems - Irvine United States } else { 564*9b241b4eSYuri Pankov /* Just do a hostname match */ 5652807a6ecSYuri Pankov if (strcasecmp(gr, host) == 0) 5662807a6ecSYuri Pankov return (response); 567b89a8333Snatalie li - Sun Microsystems - Irvine United States } 568b89a8333Snatalie li - Sun Microsystems - Irvine United States } 569b89a8333Snatalie li - Sun Microsystems - Irvine United States 570b89a8333Snatalie li - Sun Microsystems - Irvine United States nentries++; 571*9b241b4eSYuri Pankov 572*9b241b4eSYuri Pankov if (cstr == NULL) 573*9b241b4eSYuri Pankov break; 574*9b241b4eSYuri Pankov 575*9b241b4eSYuri Pankov gr = ++cstr; 576b89a8333Snatalie li - Sun Microsystems - Irvine United States } 577b89a8333Snatalie li - Sun Microsystems - Irvine United States 5782807a6ecSYuri Pankov if (clres) 5792807a6ecSYuri Pankov return (0); 580b89a8333Snatalie li - Sun Microsystems - Irvine United States 5812807a6ecSYuri Pankov return (smb_netgroup_match(clnames, access_list, nentries)); 582b89a8333Snatalie li - Sun Microsystems - Irvine United States } 583b89a8333Snatalie li - Sun Microsystems - Irvine United States 584b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 585b89a8333Snatalie li - Sun Microsystems - Irvine United States * smb_netgroup_match 586b89a8333Snatalie li - Sun Microsystems - Irvine United States * 587b89a8333Snatalie li - Sun Microsystems - Irvine United States * Check whether any of the hostnames in clnames are 588b89a8333Snatalie li - Sun Microsystems - Irvine United States * members (or non-members) of the netgroups in glist. 589b89a8333Snatalie li - Sun Microsystems - Irvine United States * Since the innetgr lookup is rather expensive, the 590b89a8333Snatalie li - Sun Microsystems - Irvine United States * result is cached. The cached entry is valid only 591b89a8333Snatalie li - Sun Microsystems - Irvine United States * for VALID_TIME seconds. This works well because 592b89a8333Snatalie li - Sun Microsystems - Irvine United States * typically these lookups occur in clusters when 593b89a8333Snatalie li - Sun Microsystems - Irvine United States * a client is mounting. 594b89a8333Snatalie li - Sun Microsystems - Irvine United States * 595b89a8333Snatalie li - Sun Microsystems - Irvine United States * Note that this routine establishes a host membership 596b89a8333Snatalie li - Sun Microsystems - Irvine United States * in a list of netgroups - we've no idea just which 597b89a8333Snatalie li - Sun Microsystems - Irvine United States * netgroup in the list it is a member of. 598b89a8333Snatalie li - Sun Microsystems - Irvine United States * 599b89a8333Snatalie li - Sun Microsystems - Irvine United States * glist is a character array containing grc strings 600b89a8333Snatalie li - Sun Microsystems - Irvine United States * representing netgroup names (optionally prefixed 601b89a8333Snatalie li - Sun Microsystems - Irvine United States * with '-'). Each string is ended with '\0' and 602b89a8333Snatalie li - Sun Microsystems - Irvine United States * followed immediately by the next string. 603b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 604b89a8333Snatalie li - Sun Microsystems - Irvine United States static boolean_t 605b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_netgroup_match(struct nd_hostservlist *clnames, char *glist, int grc) 606b89a8333Snatalie li - Sun Microsystems - Irvine United States { 607b89a8333Snatalie li - Sun Microsystems - Irvine United States char **grl; 608b89a8333Snatalie li - Sun Microsystems - Irvine United States char *gr; 609b89a8333Snatalie li - Sun Microsystems - Irvine United States int nhosts = clnames->h_cnt; 610b89a8333Snatalie li - Sun Microsystems - Irvine United States char *host; 611b89a8333Snatalie li - Sun Microsystems - Irvine United States int i, j, n; 612b89a8333Snatalie li - Sun Microsystems - Irvine United States boolean_t response; 613b89a8333Snatalie li - Sun Microsystems - Irvine United States boolean_t belong = B_FALSE; 614b89a8333Snatalie li - Sun Microsystems - Irvine United States static char *domain = NULL; 615b89a8333Snatalie li - Sun Microsystems - Irvine United States 616b89a8333Snatalie li - Sun Microsystems - Irvine United States if (domain == NULL) { 617b89a8333Snatalie li - Sun Microsystems - Irvine United States int ssize; 618b89a8333Snatalie li - Sun Microsystems - Irvine United States 619b89a8333Snatalie li - Sun Microsystems - Irvine United States domain = malloc(SYS_NMLN); 620b89a8333Snatalie li - Sun Microsystems - Irvine United States if (domain == NULL) 621b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 622b89a8333Snatalie li - Sun Microsystems - Irvine United States 623b89a8333Snatalie li - Sun Microsystems - Irvine United States ssize = sysinfo(SI_SRPC_DOMAIN, domain, SYS_NMLN); 624b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ssize > SYS_NMLN) { 625b89a8333Snatalie li - Sun Microsystems - Irvine United States free(domain); 626b89a8333Snatalie li - Sun Microsystems - Irvine United States domain = malloc(ssize); 627b89a8333Snatalie li - Sun Microsystems - Irvine United States if (domain == NULL) 628b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 629b89a8333Snatalie li - Sun Microsystems - Irvine United States ssize = sysinfo(SI_SRPC_DOMAIN, domain, ssize); 630b89a8333Snatalie li - Sun Microsystems - Irvine United States } 631b89a8333Snatalie li - Sun Microsystems - Irvine United States /* Check for error in syscall or NULL domain name */ 632b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ssize <= 1) 633b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 634b89a8333Snatalie li - Sun Microsystems - Irvine United States } 635b89a8333Snatalie li - Sun Microsystems - Irvine United States 636b89a8333Snatalie li - Sun Microsystems - Irvine United States grl = calloc(grc, sizeof (char *)); 637b89a8333Snatalie li - Sun Microsystems - Irvine United States if (grl == NULL) 638b89a8333Snatalie li - Sun Microsystems - Irvine United States return (B_FALSE); 639b89a8333Snatalie li - Sun Microsystems - Irvine United States 640b89a8333Snatalie li - Sun Microsystems - Irvine United States for (i = 0, gr = glist; i < grc && !belong; ) { 641b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 642b89a8333Snatalie li - Sun Microsystems - Irvine United States * If the netgroup name has a '-' prepended 643b89a8333Snatalie li - Sun Microsystems - Irvine United States * then a match of this name implies a failure 644b89a8333Snatalie li - Sun Microsystems - Irvine United States * instead of success. 645b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 646b89a8333Snatalie li - Sun Microsystems - Irvine United States response = (*gr != '-') ? B_TRUE : B_FALSE; 647b89a8333Snatalie li - Sun Microsystems - Irvine United States 648b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 649b89a8333Snatalie li - Sun Microsystems - Irvine United States * Subsequent names with or without a '-' (but no mix) 650b89a8333Snatalie li - Sun Microsystems - Irvine United States * can be grouped together for a single check. 651b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 652b89a8333Snatalie li - Sun Microsystems - Irvine United States for (n = 0; i < grc; i++, n++, gr += strlen(gr) + 1) { 653b89a8333Snatalie li - Sun Microsystems - Irvine United States if ((response && *gr == '-') || 654b89a8333Snatalie li - Sun Microsystems - Irvine United States (!response && *gr != '-')) 655b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 656b89a8333Snatalie li - Sun Microsystems - Irvine United States 657b89a8333Snatalie li - Sun Microsystems - Irvine United States grl[n] = response ? gr : gr + 1; 658b89a8333Snatalie li - Sun Microsystems - Irvine United States } 659b89a8333Snatalie li - Sun Microsystems - Irvine United States 660b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 661b89a8333Snatalie li - Sun Microsystems - Irvine United States * Check the netgroup for each 662b89a8333Snatalie li - Sun Microsystems - Irvine United States * of the hosts names (usually just one). 663b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 664b89a8333Snatalie li - Sun Microsystems - Irvine United States for (j = 0; j < nhosts && !belong; j++) { 665b89a8333Snatalie li - Sun Microsystems - Irvine United States host = clnames->h_hostservs[j].h_host; 666b89a8333Snatalie li - Sun Microsystems - Irvine United States if (__multi_innetgr(n, grl, 1, &host, 0, NULL, 667b89a8333Snatalie li - Sun Microsystems - Irvine United States 1, &domain)) 668b89a8333Snatalie li - Sun Microsystems - Irvine United States belong = B_TRUE; 669b89a8333Snatalie li - Sun Microsystems - Irvine United States } 670b89a8333Snatalie li - Sun Microsystems - Irvine United States } 671b89a8333Snatalie li - Sun Microsystems - Irvine United States 672b89a8333Snatalie li - Sun Microsystems - Irvine United States free(grl); 673b89a8333Snatalie li - Sun Microsystems - Irvine United States return (belong ? response : B_FALSE); 674b89a8333Snatalie li - Sun Microsystems - Irvine United States } 6756d57f833SAlan Wright 6766d57f833SAlan Wright /* 6776d57f833SAlan Wright * Resolve the ZFS dataset from a path. 67829bd2886SAlan Wright * Returns, 67929bd2886SAlan Wright * 0 = On success. 68029bd2886SAlan Wright * -1 = Failure to open /etc/mnttab file or to get ZFS dataset. 6816d57f833SAlan Wright */ 6826d57f833SAlan Wright int 6836d57f833SAlan Wright smb_getdataset(const char *path, char *dataset, size_t len) 6846d57f833SAlan Wright { 6856d57f833SAlan Wright char tmppath[MAXPATHLEN]; 6866d57f833SAlan Wright char *cp; 6876d57f833SAlan Wright FILE *fp; 6886d57f833SAlan Wright struct mnttab mnttab; 6896d57f833SAlan Wright struct mnttab mntpref; 6906d57f833SAlan Wright int rc = -1; 6916d57f833SAlan Wright 6926d57f833SAlan Wright if ((fp = fopen(MNTTAB, "r")) == NULL) 6936d57f833SAlan Wright return (-1); 6946d57f833SAlan Wright 6956d57f833SAlan Wright (void) memset(&mnttab, '\0', sizeof (mnttab)); 6966d57f833SAlan Wright (void) strlcpy(tmppath, path, MAXPATHLEN); 6976d57f833SAlan Wright cp = tmppath; 6986d57f833SAlan Wright 6996d57f833SAlan Wright while (*cp != '\0') { 7006d57f833SAlan Wright resetmnttab(fp); 7016d57f833SAlan Wright (void) memset(&mntpref, '\0', sizeof (mntpref)); 7026d57f833SAlan Wright mntpref.mnt_mountp = tmppath; 7036d57f833SAlan Wright 7046d57f833SAlan Wright if (getmntany(fp, &mnttab, &mntpref) == 0) { 70529bd2886SAlan Wright if (mnttab.mnt_fstype == NULL) 70629bd2886SAlan Wright break; 70729bd2886SAlan Wright 70829bd2886SAlan Wright if (strcmp(mnttab.mnt_fstype, "zfs") != 0) 70929bd2886SAlan Wright break; 7106d57f833SAlan Wright /* 7116d57f833SAlan Wright * Ensure that there are no leading slashes 7126d57f833SAlan Wright * (required for zfs_open). 7136d57f833SAlan Wright */ 7146d57f833SAlan Wright cp = mnttab.mnt_special; 7156d57f833SAlan Wright cp += strspn(cp, "/"); 7166d57f833SAlan Wright (void) strlcpy(dataset, cp, len); 7176d57f833SAlan Wright rc = 0; 7186d57f833SAlan Wright break; 7196d57f833SAlan Wright } 7206d57f833SAlan Wright 721fc724630SAlan Wright if (strcmp(tmppath, "/") == 0) 722fc724630SAlan Wright break; 723fc724630SAlan Wright 724fc724630SAlan Wright if ((cp = strrchr(tmppath, '/')) == NULL) 725fc724630SAlan Wright break; 726fc724630SAlan Wright 727fc724630SAlan Wright /* 728fc724630SAlan Wright * The path has multiple components. 729fc724630SAlan Wright * Remove the last component and try again. 730fc724630SAlan Wright */ 731fc724630SAlan Wright *cp = '\0'; 732fc724630SAlan Wright if (tmppath[0] == '\0') 733fc724630SAlan Wright (void) strcpy(tmppath, "/"); 7346d57f833SAlan Wright 7356d57f833SAlan Wright cp = tmppath; 7366d57f833SAlan Wright } 7376d57f833SAlan Wright 7386d57f833SAlan Wright (void) fclose(fp); 7396d57f833SAlan Wright return (rc); 7406d57f833SAlan Wright } 74129bd2886SAlan Wright 7421fcced4cSJordan Brown /* 7431fcced4cSJordan Brown * smb_dlopen 7441fcced4cSJordan Brown * 7451fcced4cSJordan Brown * Check to see if an interposer library exists. If it exists 7461fcced4cSJordan Brown * and reports a valid version number and key (UUID), return 7471fcced4cSJordan Brown * a handle to the library. Otherwise, return NULL. 7481fcced4cSJordan Brown */ 7491fcced4cSJordan Brown void * 7501fcced4cSJordan Brown smb_dlopen(void) 7511fcced4cSJordan Brown { 7521fcced4cSJordan Brown uuid_t uuid; 7531fcced4cSJordan Brown void *interposer_hdl; 7541fcced4cSJordan Brown typedef int (*smbex_versionfn_t)(smbex_version_t *); 7551fcced4cSJordan Brown smbex_versionfn_t getversion; 7561fcced4cSJordan Brown smbex_version_t *version; 7571fcced4cSJordan Brown 7581fcced4cSJordan Brown bzero(&uuid, sizeof (uuid_t)); 7591fcced4cSJordan Brown if (uuid_parse(SMBEX_KEY, uuid) < 0) 7601fcced4cSJordan Brown return (NULL); 7611fcced4cSJordan Brown 7621fcced4cSJordan Brown interposer_hdl = dlopen(SMB_LIB_ALT, RTLD_NOW | RTLD_LOCAL); 7631fcced4cSJordan Brown if (interposer_hdl == NULL) 7641fcced4cSJordan Brown return (NULL); 7651fcced4cSJordan Brown 7661fcced4cSJordan Brown bzero(&getversion, sizeof (smbex_versionfn_t)); 7671fcced4cSJordan Brown getversion = (smbex_versionfn_t)dlsym(interposer_hdl, 7681fcced4cSJordan Brown "smbex_get_version"); 7691fcced4cSJordan Brown if ((getversion == NULL) || 7701fcced4cSJordan Brown (version = malloc(sizeof (smbex_version_t))) == NULL) { 7711fcced4cSJordan Brown (void) dlclose(interposer_hdl); 7721fcced4cSJordan Brown return (NULL); 7731fcced4cSJordan Brown } 7741fcced4cSJordan Brown bzero(version, sizeof (smbex_version_t)); 7751fcced4cSJordan Brown 7761fcced4cSJordan Brown if ((getversion(version) != 0) || 7771fcced4cSJordan Brown (version->v_version != SMBEX_VERSION) || 7781fcced4cSJordan Brown (uuid_compare(version->v_uuid, uuid) != 0)) { 7791fcced4cSJordan Brown free(version); 7801fcced4cSJordan Brown (void) dlclose(interposer_hdl); 7811fcced4cSJordan Brown return (NULL); 7821fcced4cSJordan Brown } 7831fcced4cSJordan Brown 7841fcced4cSJordan Brown free(version); 7851fcced4cSJordan Brown return (interposer_hdl); 7861fcced4cSJordan Brown } 7871fcced4cSJordan Brown 7881fcced4cSJordan Brown /* 7891fcced4cSJordan Brown * smb_dlclose 7901fcced4cSJordan Brown * 7911fcced4cSJordan Brown * Closes handle to the interposed library. 7921fcced4cSJordan Brown */ 7931fcced4cSJordan Brown void 7941fcced4cSJordan Brown smb_dlclose(void *handle) 7951fcced4cSJordan Brown { 7961fcced4cSJordan Brown if (handle) 7971fcced4cSJordan Brown (void) dlclose(handle); 7981fcced4cSJordan Brown } 7991fcced4cSJordan Brown 80029bd2886SAlan Wright /* 8019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * This function is a wrapper for getnameinfo() to look up a hostname given an 8029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * IP address. The hostname returned by this function is used for constructing 8039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * the service principal name field of KRB AP-REQs. Hence, it should be 8049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * converted to lowercase for RFC 4120 section 6.2.1 conformance. 80529bd2886SAlan Wright */ 80629bd2886SAlan Wright int 80729bd2886SAlan Wright smb_getnameinfo(smb_inaddr_t *ip, char *hostname, int hostlen, int flags) 80829bd2886SAlan Wright { 80929bd2886SAlan Wright socklen_t salen; 81029bd2886SAlan Wright struct sockaddr_in6 sin6; 81129bd2886SAlan Wright struct sockaddr_in sin; 81229bd2886SAlan Wright void *sp; 8139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 81429bd2886SAlan Wright 81529bd2886SAlan Wright if (ip->a_family == AF_INET) { 81629bd2886SAlan Wright salen = sizeof (struct sockaddr_in); 81729bd2886SAlan Wright sin.sin_family = ip->a_family; 81829bd2886SAlan Wright sin.sin_port = 0; 81929bd2886SAlan Wright sin.sin_addr.s_addr = ip->a_ipv4; 82029bd2886SAlan Wright sp = &sin; 82129bd2886SAlan Wright } else { 82229bd2886SAlan Wright salen = sizeof (struct sockaddr_in6); 82329bd2886SAlan Wright sin6.sin6_family = ip->a_family; 82429bd2886SAlan Wright sin6.sin6_port = 0; 82529bd2886SAlan Wright (void) memcpy(&sin6.sin6_addr.s6_addr, &ip->a_ipv6, 82629bd2886SAlan Wright sizeof (sin6.sin6_addr.s6_addr)); 82729bd2886SAlan Wright sp = &sin6; 82829bd2886SAlan Wright } 8299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = (getnameinfo((struct sockaddr *)sp, salen, 8319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hostname, hostlen, NULL, 0, flags))) == 0) 8329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_strlwr(hostname); 8339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 83529bd2886SAlan Wright } 836fe1c642dSBill Krier 837fe1c642dSBill Krier /* 838fe1c642dSBill Krier * A share name is considered invalid if it contains control 839fe1c642dSBill Krier * characters or any of the following characters (MSDN 236388). 840fe1c642dSBill Krier * 841fe1c642dSBill Krier * " / \ [ ] : | < > + ; , ? * = 842fe1c642dSBill Krier */ 843fe1c642dSBill Krier uint32_t 844fe1c642dSBill Krier smb_name_validate_share(const char *sharename) 845fe1c642dSBill Krier { 846fe1c642dSBill Krier const char *invalid = "\"/\\[]:|<>+;,?*="; 847fe1c642dSBill Krier const char *p; 848fe1c642dSBill Krier 849fe1c642dSBill Krier if (sharename == NULL) 850fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 851fe1c642dSBill Krier 852fe1c642dSBill Krier if (strpbrk(sharename, invalid) != NULL) 853fe1c642dSBill Krier return (ERROR_INVALID_NAME); 854fe1c642dSBill Krier 855fe1c642dSBill Krier for (p = sharename; *p != '\0'; p++) { 856fe1c642dSBill Krier if (iscntrl(*p)) 857fe1c642dSBill Krier return (ERROR_INVALID_NAME); 858fe1c642dSBill Krier } 859fe1c642dSBill Krier 860fe1c642dSBill Krier return (ERROR_SUCCESS); 861fe1c642dSBill Krier } 862fe1c642dSBill Krier 863fe1c642dSBill Krier /* 864fe1c642dSBill Krier * User and group names are limited to 256 characters, cannot be terminated 865fe1c642dSBill Krier * by '.' and must not contain control characters or any of the following 866fe1c642dSBill Krier * characters. 867fe1c642dSBill Krier * 868fe1c642dSBill Krier * " / \ [ ] < > + ; , ? * = @ 869fe1c642dSBill Krier */ 870fe1c642dSBill Krier uint32_t 871fe1c642dSBill Krier smb_name_validate_account(const char *name) 872fe1c642dSBill Krier { 873fe1c642dSBill Krier const char *invalid = "\"/\\[]<>+;,?*=@"; 874fe1c642dSBill Krier const char *p; 875fe1c642dSBill Krier int len; 876fe1c642dSBill Krier 877fe1c642dSBill Krier if ((name == NULL) || (*name == '\0')) 878fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 879fe1c642dSBill Krier 880fe1c642dSBill Krier len = strlen(name); 881fe1c642dSBill Krier if ((len > MAXNAMELEN) || (name[len - 1] == '.')) 882fe1c642dSBill Krier return (ERROR_INVALID_NAME); 883fe1c642dSBill Krier 884fe1c642dSBill Krier if (strpbrk(name, invalid) != NULL) 885fe1c642dSBill Krier return (ERROR_INVALID_NAME); 886fe1c642dSBill Krier 887fe1c642dSBill Krier for (p = name; *p != '\0'; p++) { 888fe1c642dSBill Krier if (iscntrl(*p)) 889fe1c642dSBill Krier return (ERROR_INVALID_NAME); 890fe1c642dSBill Krier } 891fe1c642dSBill Krier 892fe1c642dSBill Krier return (ERROR_SUCCESS); 893fe1c642dSBill Krier } 894fe1c642dSBill Krier 895fe1c642dSBill Krier /* 896fe1c642dSBill Krier * Check a domain name for RFC 1035 and 1123 compliance. Domain names may 897fe1c642dSBill Krier * contain alphanumeric characters, hyphens and dots. The first and last 898fe1c642dSBill Krier * character of a label must be alphanumeric. Interior characters may be 899fe1c642dSBill Krier * alphanumeric or hypens. 900fe1c642dSBill Krier * 901fe1c642dSBill Krier * Domain names should not contain underscores but we allow them because 902fe1c642dSBill Krier * Windows names are often in non-compliance with this rule. 903fe1c642dSBill Krier */ 904fe1c642dSBill Krier uint32_t 905fe1c642dSBill Krier smb_name_validate_domain(const char *domain) 906fe1c642dSBill Krier { 907fe1c642dSBill Krier boolean_t new_label = B_TRUE; 908fe1c642dSBill Krier const char *p; 909fe1c642dSBill Krier char label_terminator; 910fe1c642dSBill Krier 911fe1c642dSBill Krier if (domain == NULL) 912fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 913fe1c642dSBill Krier 914fe1c642dSBill Krier if (*domain == '\0') 915fe1c642dSBill Krier return (ERROR_INVALID_NAME); 916fe1c642dSBill Krier 917fe1c642dSBill Krier label_terminator = *domain; 918fe1c642dSBill Krier 919fe1c642dSBill Krier for (p = domain; *p != '\0'; ++p) { 920fe1c642dSBill Krier if (new_label) { 921fe1c642dSBill Krier if (!isalnum(*p)) 922fe1c642dSBill Krier return (ERROR_INVALID_NAME); 923fe1c642dSBill Krier new_label = B_FALSE; 924fe1c642dSBill Krier label_terminator = *p; 925fe1c642dSBill Krier continue; 926fe1c642dSBill Krier } 927fe1c642dSBill Krier 928fe1c642dSBill Krier if (*p == '.') { 929fe1c642dSBill Krier if (!isalnum(label_terminator)) 930fe1c642dSBill Krier return (ERROR_INVALID_NAME); 931fe1c642dSBill Krier new_label = B_TRUE; 932fe1c642dSBill Krier label_terminator = *p; 933fe1c642dSBill Krier continue; 934fe1c642dSBill Krier } 935fe1c642dSBill Krier 936fe1c642dSBill Krier label_terminator = *p; 937fe1c642dSBill Krier 938fe1c642dSBill Krier if (isalnum(*p) || *p == '-' || *p == '_') 939fe1c642dSBill Krier continue; 940fe1c642dSBill Krier 941fe1c642dSBill Krier return (ERROR_INVALID_NAME); 942fe1c642dSBill Krier } 943fe1c642dSBill Krier 944fe1c642dSBill Krier if (!isalnum(label_terminator)) 945fe1c642dSBill Krier return (ERROR_INVALID_NAME); 946fe1c642dSBill Krier 947fe1c642dSBill Krier return (ERROR_SUCCESS); 948fe1c642dSBill Krier } 949fe1c642dSBill Krier 950fe1c642dSBill Krier /* 951fe1c642dSBill Krier * A NetBIOS domain name can contain letters (a-zA-Z), numbers (0-9) and 952fe1c642dSBill Krier * hyphens. 953fe1c642dSBill Krier * 954fe1c642dSBill Krier * It cannot: 955fe1c642dSBill Krier * - be blank or longer than 15 chracters 956fe1c642dSBill Krier * - contain all numbers 957fe1c642dSBill Krier * - be the same as the computer name 958fe1c642dSBill Krier */ 959fe1c642dSBill Krier uint32_t 960fe1c642dSBill Krier smb_name_validate_nbdomain(const char *name) 961fe1c642dSBill Krier { 962fe1c642dSBill Krier char netbiosname[NETBIOS_NAME_SZ]; 963fe1c642dSBill Krier const char *p; 964fe1c642dSBill Krier int len; 965fe1c642dSBill Krier 966fe1c642dSBill Krier if (name == NULL) 967fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 968fe1c642dSBill Krier 969fe1c642dSBill Krier len = strlen(name); 970fe1c642dSBill Krier if (len == 0 || len >= NETBIOS_NAME_SZ) 971fe1c642dSBill Krier return (ERROR_INVALID_NAME); 972fe1c642dSBill Krier 973fe1c642dSBill Krier if (strspn(name, "0123456789") == len) 974fe1c642dSBill Krier return (ERROR_INVALID_NAME); 975fe1c642dSBill Krier 976fe1c642dSBill Krier if (smb_getnetbiosname(netbiosname, NETBIOS_NAME_SZ) == 0) { 977fe1c642dSBill Krier if (smb_strcasecmp(name, netbiosname, 0) == 0) 978fe1c642dSBill Krier return (ERROR_INVALID_NAME); 979fe1c642dSBill Krier } 980fe1c642dSBill Krier 981fe1c642dSBill Krier for (p = name; *p != '\0'; ++p) { 982fe1c642dSBill Krier if (isalnum(*p) || *p == '-' || *p == '_') 983fe1c642dSBill Krier continue; 984fe1c642dSBill Krier 985fe1c642dSBill Krier return (ERROR_INVALID_NAME); 986fe1c642dSBill Krier } 987fe1c642dSBill Krier 988fe1c642dSBill Krier return (ERROR_SUCCESS); 989fe1c642dSBill Krier } 990fe1c642dSBill Krier 991fe1c642dSBill Krier /* 992fe1c642dSBill Krier * A workgroup name can contain 1 to 15 characters but cannot be the same 993fe1c642dSBill Krier * as the NetBIOS name. The name must begin with a letter or number. 994fe1c642dSBill Krier * 995fe1c642dSBill Krier * The name cannot consist entirely of spaces or dots, which is covered 996fe1c642dSBill Krier * by the requirement that the name must begin with an alphanumeric 997fe1c642dSBill Krier * character. 998fe1c642dSBill Krier * 999fe1c642dSBill Krier * The name must not contain control characters or any of the following 1000fe1c642dSBill Krier * characters. 1001fe1c642dSBill Krier * 1002fe1c642dSBill Krier * " / \ [ ] : | < > + = ; , ? 1003fe1c642dSBill Krier */ 1004fe1c642dSBill Krier uint32_t 1005fe1c642dSBill Krier smb_name_validate_workgroup(const char *workgroup) 1006fe1c642dSBill Krier { 1007fe1c642dSBill Krier char netbiosname[NETBIOS_NAME_SZ]; 1008fe1c642dSBill Krier const char *invalid = "\"/\\[]:|<>+=;,?"; 1009fe1c642dSBill Krier const char *p; 1010fe1c642dSBill Krier 1011fe1c642dSBill Krier if (workgroup == NULL) 1012fe1c642dSBill Krier return (ERROR_INVALID_PARAMETER); 1013fe1c642dSBill Krier 1014fe1c642dSBill Krier if (*workgroup == '\0' || (!isalnum(*workgroup))) 1015fe1c642dSBill Krier return (ERROR_INVALID_NAME); 1016fe1c642dSBill Krier 1017fe1c642dSBill Krier if (strlen(workgroup) >= NETBIOS_NAME_SZ) 1018fe1c642dSBill Krier return (ERROR_INVALID_NAME); 1019fe1c642dSBill Krier 1020fe1c642dSBill Krier if (smb_getnetbiosname(netbiosname, NETBIOS_NAME_SZ) == 0) { 1021fe1c642dSBill Krier if (smb_strcasecmp(workgroup, netbiosname, 0) == 0) 1022fe1c642dSBill Krier return (ERROR_INVALID_NAME); 1023fe1c642dSBill Krier } 1024fe1c642dSBill Krier 1025fe1c642dSBill Krier if (strpbrk(workgroup, invalid) != NULL) 1026fe1c642dSBill Krier return (ERROR_INVALID_NAME); 1027fe1c642dSBill Krier 1028fe1c642dSBill Krier for (p = workgroup; *p != '\0'; p++) { 1029fe1c642dSBill Krier if (iscntrl(*p)) 1030fe1c642dSBill Krier return (ERROR_INVALID_NAME); 1031fe1c642dSBill Krier } 1032fe1c642dSBill Krier 1033fe1c642dSBill Krier return (ERROR_SUCCESS); 1034fe1c642dSBill Krier } 1035fe1c642dSBill Krier 10369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 10379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Check for invalid characters in the given path. The list of invalid 10389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * characters includes control characters and the following: 10399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 10409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * " / \ [ ] : | < > + ; , ? * = 10419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 10429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Since this is checking a path not each component, '/' is accepted 10439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * as separator not an invalid character, except as the first character 10449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * since this is supposed to be a relative path. 10459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 10469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t 10479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_name_validate_rpath(const char *relpath) 10489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 10499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *invalid = "\"\\[]:|<>+;,?*="; 10509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *cp; 10519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((relpath == NULL) || (*relpath == '\0') || (*relpath == '/')) 10539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_INVALID_NAME); 10549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (strpbrk(relpath, invalid)) 10569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_INVALID_NAME); 10579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States for (cp = (char *)relpath; *cp != '\0'; cp++) { 10599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (iscntrl(*cp)) 10609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_INVALID_NAME); 10619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 10629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ERROR_SUCCESS); 10649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 10659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1066fe1c642dSBill Krier /* 1067fe1c642dSBill Krier * Parse a string to obtain the account and domain names as separate strings. 1068fe1c642dSBill Krier * 1069fe1c642dSBill Krier * Names containing a backslash ('\') are known as qualified or composite 1070fe1c642dSBill Krier * names. The string preceding the backslash should be the domain name 1071fe1c642dSBill Krier * and the string following the slash should be a name within that domain. 1072fe1c642dSBill Krier * 1073fe1c642dSBill Krier * Names that do not contain a backslash are known as isolated names. 1074fe1c642dSBill Krier * An isolated name may be a single label, such as john, or may be in 1075fe1c642dSBill Krier * user principal name (UPN) form, such as john@example.com. 1076fe1c642dSBill Krier * 1077fe1c642dSBill Krier * domain\name 1078fe1c642dSBill Krier * domain/name 1079fe1c642dSBill Krier * name 1080fe1c642dSBill Krier * name@domain 1081fe1c642dSBill Krier * 1082fe1c642dSBill Krier * If we encounter any of the forms above in arg, the @, / or \ separator 1083fe1c642dSBill Krier * is replaced by \0 and the name and domain pointers are set to point to 1084fe1c642dSBill Krier * the appropriate components in arg. Otherwise, name and domain pointers 1085fe1c642dSBill Krier * will be set to NULL. 1086fe1c642dSBill Krier */ 1087fe1c642dSBill Krier void 1088fe1c642dSBill Krier smb_name_parse(char *arg, char **account, char **domain) 1089fe1c642dSBill Krier { 1090fe1c642dSBill Krier char *p; 1091fe1c642dSBill Krier 1092fe1c642dSBill Krier *account = NULL; 1093fe1c642dSBill Krier *domain = NULL; 1094fe1c642dSBill Krier 1095fe1c642dSBill Krier if ((p = strpbrk(arg, "/\\@")) != NULL) { 1096fe1c642dSBill Krier if (*p == '@') { 1097fe1c642dSBill Krier *p = '\0'; 1098fe1c642dSBill Krier ++p; 1099fe1c642dSBill Krier *domain = p; 1100fe1c642dSBill Krier *account = arg; 1101fe1c642dSBill Krier } else { 1102fe1c642dSBill Krier *p = '\0'; 1103fe1c642dSBill Krier ++p; 1104fe1c642dSBill Krier *account = p; 1105fe1c642dSBill Krier *domain = arg; 1106fe1c642dSBill Krier } 1107fe1c642dSBill Krier } 1108fe1c642dSBill Krier } 1109148c5f43SAlan Wright 1110148c5f43SAlan Wright /* 1111148c5f43SAlan Wright * The txid is an arbitrary transaction. A new txid is returned on each call. 1112148c5f43SAlan Wright * 1113148c5f43SAlan Wright * 0 or -1 are not assigned so that they can be used to detect 1114148c5f43SAlan Wright * invalid conditions. 1115148c5f43SAlan Wright */ 1116148c5f43SAlan Wright uint32_t 1117148c5f43SAlan Wright smb_get_txid(void) 1118148c5f43SAlan Wright { 1119148c5f43SAlan Wright static mutex_t txmutex; 1120148c5f43SAlan Wright static uint32_t txid; 1121148c5f43SAlan Wright uint32_t txid_ret; 1122148c5f43SAlan Wright 1123148c5f43SAlan Wright (void) mutex_lock(&txmutex); 1124148c5f43SAlan Wright 1125148c5f43SAlan Wright if (txid == 0) 1126148c5f43SAlan Wright txid = time(NULL); 1127148c5f43SAlan Wright 1128148c5f43SAlan Wright do { 1129148c5f43SAlan Wright ++txid; 1130148c5f43SAlan Wright } while (txid == 0 || txid == (uint32_t)-1); 1131148c5f43SAlan Wright 1132148c5f43SAlan Wright txid_ret = txid; 1133148c5f43SAlan Wright (void) mutex_unlock(&txmutex); 1134148c5f43SAlan Wright 1135148c5f43SAlan Wright return (txid_ret); 1136148c5f43SAlan Wright } 1137148c5f43SAlan Wright 1138148c5f43SAlan Wright /* 1139148c5f43SAlan Wright * Creates a log object and inserts it into a list of logs. 1140148c5f43SAlan Wright */ 1141148c5f43SAlan Wright smb_log_hdl_t 1142148c5f43SAlan Wright smb_log_create(int max_cnt, char *name) 1143148c5f43SAlan Wright { 1144148c5f43SAlan Wright smb_loglist_item_t *log_node; 1145148c5f43SAlan Wright smb_log_t *log = NULL; 1146148c5f43SAlan Wright smb_log_hdl_t handle = 0; 1147148c5f43SAlan Wright 1148148c5f43SAlan Wright if (max_cnt <= 0 || name == NULL) 1149148c5f43SAlan Wright return (0); 1150148c5f43SAlan Wright 1151148c5f43SAlan Wright (void) mutex_lock(&smb_loglist.ll_mtx); 1152148c5f43SAlan Wright 1153148c5f43SAlan Wright log_node = malloc(sizeof (smb_loglist_item_t)); 1154148c5f43SAlan Wright 1155148c5f43SAlan Wright if (log_node != NULL) { 1156148c5f43SAlan Wright log = &log_node->lli_log; 1157148c5f43SAlan Wright 1158148c5f43SAlan Wright bzero(log, sizeof (smb_log_t)); 1159148c5f43SAlan Wright 1160148c5f43SAlan Wright handle = log->l_handle = smb_get_txid(); 1161148c5f43SAlan Wright log->l_max_cnt = max_cnt; 1162148c5f43SAlan Wright (void) snprintf(log->l_file, sizeof (log->l_file), 1163148c5f43SAlan Wright SMB_LOG_FILE_FMT, name); 1164148c5f43SAlan Wright 1165148c5f43SAlan Wright list_create(&log->l_list, sizeof (smb_log_item_t), 1166148c5f43SAlan Wright offsetof(smb_log_item_t, li_lnd)); 1167148c5f43SAlan Wright 1168148c5f43SAlan Wright if (smb_loglist.ll_list.list_size == 0) 1169148c5f43SAlan Wright list_create(&smb_loglist.ll_list, 1170148c5f43SAlan Wright sizeof (smb_loglist_item_t), 1171148c5f43SAlan Wright offsetof(smb_loglist_item_t, lli_lnd)); 1172148c5f43SAlan Wright 1173148c5f43SAlan Wright list_insert_tail(&smb_loglist.ll_list, log_node); 1174148c5f43SAlan Wright } 1175148c5f43SAlan Wright 1176148c5f43SAlan Wright (void) mutex_unlock(&smb_loglist.ll_mtx); 1177148c5f43SAlan Wright 1178148c5f43SAlan Wright return (handle); 1179148c5f43SAlan Wright } 1180148c5f43SAlan Wright 1181148c5f43SAlan Wright /* 1182148c5f43SAlan Wright * Keep the most recent log entries, based on max count. 1183148c5f43SAlan Wright * If the priority is LOG_ERR or higher then the entire log is 1184148c5f43SAlan Wright * dumped to a file. 1185148c5f43SAlan Wright * 1186148c5f43SAlan Wright * The date format for each message is the same as a syslog entry. 1187148c5f43SAlan Wright * 1188148c5f43SAlan Wright * The log is also added to syslog via smb_log_trace(). 1189148c5f43SAlan Wright */ 1190148c5f43SAlan Wright void 1191148c5f43SAlan Wright smb_log(smb_log_hdl_t hdl, int priority, const char *fmt, ...) 1192148c5f43SAlan Wright { 1193148c5f43SAlan Wright va_list ap; 1194148c5f43SAlan Wright smb_log_t *log; 1195148c5f43SAlan Wright smb_log_item_t *msg; 1196148c5f43SAlan Wright time_t now; 1197148c5f43SAlan Wright struct tm *tm; 1198148c5f43SAlan Wright char timebuf[SMB_TIMEBUF_SZ]; 1199148c5f43SAlan Wright char buf[SMB_TRACEBUF_SZ]; 1200148c5f43SAlan Wright char netbiosname[NETBIOS_NAME_SZ]; 1201148c5f43SAlan Wright char *pri_name; 1202148c5f43SAlan Wright int i; 1203148c5f43SAlan Wright 1204148c5f43SAlan Wright va_start(ap, fmt); 1205148c5f43SAlan Wright (void) vsnprintf(buf, SMB_TRACEBUF_SZ, fmt, ap); 1206148c5f43SAlan Wright va_end(ap); 1207148c5f43SAlan Wright 1208148c5f43SAlan Wright priority &= LOG_PRIMASK; 1209148c5f43SAlan Wright smb_log_trace(priority, buf); 1210148c5f43SAlan Wright 1211148c5f43SAlan Wright if ((log = smb_log_get(hdl)) == NULL) 1212148c5f43SAlan Wright return; 1213148c5f43SAlan Wright 1214148c5f43SAlan Wright (void) mutex_lock(&log->l_mtx); 1215148c5f43SAlan Wright 1216148c5f43SAlan Wright (void) time(&now); 1217148c5f43SAlan Wright tm = localtime(&now); 1218148c5f43SAlan Wright (void) strftime(timebuf, SMB_TIMEBUF_SZ, "%b %d %H:%M:%S", tm); 1219148c5f43SAlan Wright 1220148c5f43SAlan Wright if (smb_getnetbiosname(netbiosname, NETBIOS_NAME_SZ) != 0) 1221148c5f43SAlan Wright (void) strlcpy(netbiosname, "unknown", NETBIOS_NAME_SZ); 1222148c5f43SAlan Wright 1223148c5f43SAlan Wright if (log->l_cnt == log->l_max_cnt) { 1224148c5f43SAlan Wright msg = list_head(&log->l_list); 1225148c5f43SAlan Wright list_remove(&log->l_list, msg); 1226148c5f43SAlan Wright } else { 1227148c5f43SAlan Wright if ((msg = malloc(sizeof (smb_log_item_t))) == NULL) { 1228148c5f43SAlan Wright (void) mutex_unlock(&log->l_mtx); 1229148c5f43SAlan Wright return; 1230148c5f43SAlan Wright } 1231148c5f43SAlan Wright log->l_cnt++; 1232148c5f43SAlan Wright } 1233148c5f43SAlan Wright 1234148c5f43SAlan Wright pri_name = "info"; 1235148c5f43SAlan Wright for (i = 0; i < sizeof (smb_log_pri) / sizeof (smb_log_pri[0]); i++) { 1236148c5f43SAlan Wright if (priority == smb_log_pri[i].lp_value) { 1237148c5f43SAlan Wright pri_name = smb_log_pri[i].lp_name; 1238148c5f43SAlan Wright break; 1239148c5f43SAlan Wright } 1240148c5f43SAlan Wright } 1241148c5f43SAlan Wright 1242148c5f43SAlan Wright (void) snprintf(msg->li_msg, SMB_LOG_LINE_SZ, 1243148c5f43SAlan Wright "%s %s smb[%d]: [ID 0 daemon.%s] %s", 1244148c5f43SAlan Wright timebuf, netbiosname, getpid(), pri_name, buf); 1245148c5f43SAlan Wright list_insert_tail(&log->l_list, msg); 1246148c5f43SAlan Wright 1247148c5f43SAlan Wright if (priority <= LOG_ERR) 1248148c5f43SAlan Wright smb_log_dump(log); 1249148c5f43SAlan Wright 1250148c5f43SAlan Wright (void) mutex_unlock(&log->l_mtx); 1251148c5f43SAlan Wright } 1252148c5f43SAlan Wright 1253148c5f43SAlan Wright /* 1254148c5f43SAlan Wright * Dumps all the logs in the log list. 1255148c5f43SAlan Wright */ 1256148c5f43SAlan Wright void 1257148c5f43SAlan Wright smb_log_dumpall() 1258148c5f43SAlan Wright { 1259148c5f43SAlan Wright smb_loglist_item_t *log_node; 1260148c5f43SAlan Wright 1261148c5f43SAlan Wright (void) mutex_lock(&smb_loglist.ll_mtx); 1262148c5f43SAlan Wright 1263148c5f43SAlan Wright log_node = list_head(&smb_loglist.ll_list); 1264148c5f43SAlan Wright 1265148c5f43SAlan Wright while (log_node != NULL) { 1266148c5f43SAlan Wright smb_log_dump(&log_node->lli_log); 1267148c5f43SAlan Wright log_node = list_next(&smb_loglist.ll_list, log_node); 1268148c5f43SAlan Wright } 1269148c5f43SAlan Wright 1270148c5f43SAlan Wright (void) mutex_unlock(&smb_loglist.ll_mtx); 1271148c5f43SAlan Wright } 1272148c5f43SAlan Wright 1273148c5f43SAlan Wright static void 1274148c5f43SAlan Wright smb_log_trace(int priority, const char *s) 1275148c5f43SAlan Wright { 1276148c5f43SAlan Wright syslog(priority, "%s", s); 1277148c5f43SAlan Wright } 1278148c5f43SAlan Wright 1279148c5f43SAlan Wright static smb_log_t * 1280148c5f43SAlan Wright smb_log_get(smb_log_hdl_t hdl) 1281148c5f43SAlan Wright { 1282148c5f43SAlan Wright smb_loglist_item_t *log_node; 1283148c5f43SAlan Wright smb_log_t *log; 1284148c5f43SAlan Wright 1285148c5f43SAlan Wright (void) mutex_lock(&smb_loglist.ll_mtx); 1286148c5f43SAlan Wright 1287148c5f43SAlan Wright log_node = list_head(&smb_loglist.ll_list); 1288148c5f43SAlan Wright 1289148c5f43SAlan Wright while (log_node != NULL) { 1290148c5f43SAlan Wright if (log_node->lli_log.l_handle == hdl) { 1291148c5f43SAlan Wright log = &log_node->lli_log; 1292148c5f43SAlan Wright (void) mutex_unlock(&smb_loglist.ll_mtx); 1293148c5f43SAlan Wright return (log); 1294148c5f43SAlan Wright } 1295148c5f43SAlan Wright log_node = list_next(&smb_loglist.ll_list, log_node); 1296148c5f43SAlan Wright } 1297148c5f43SAlan Wright 1298148c5f43SAlan Wright (void) mutex_unlock(&smb_loglist.ll_mtx); 1299148c5f43SAlan Wright return (NULL); 1300148c5f43SAlan Wright } 1301148c5f43SAlan Wright 1302148c5f43SAlan Wright /* 1303148c5f43SAlan Wright * Dumps the log to a file. 1304148c5f43SAlan Wright */ 1305148c5f43SAlan Wright static void 1306148c5f43SAlan Wright smb_log_dump(smb_log_t *log) 1307148c5f43SAlan Wright { 1308148c5f43SAlan Wright smb_log_item_t *msg; 1309148c5f43SAlan Wright FILE *fp; 1310148c5f43SAlan Wright 1311148c5f43SAlan Wright if ((fp = fopen(log->l_file, "w")) == NULL) 1312148c5f43SAlan Wright return; 1313148c5f43SAlan Wright 1314148c5f43SAlan Wright msg = list_head(&log->l_list); 1315148c5f43SAlan Wright 1316148c5f43SAlan Wright while (msg != NULL) { 1317148c5f43SAlan Wright (void) fprintf(fp, "%s\n", msg->li_msg); 1318148c5f43SAlan Wright msg = list_next(&log->l_list, msg); 1319148c5f43SAlan Wright } 1320148c5f43SAlan Wright 1321148c5f43SAlan Wright (void) fclose(fp); 1322148c5f43SAlan Wright } 1323