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
hexdump_offset(unsigned char * buffer,int nbytes,unsigned long * start)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
hexdump(unsigned char * buffer,int nbytes)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
bintohex(const char * srcbuf,size_t srclen,char * hexbuf,size_t hexlen)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
hextobin(const char * hexbuf,size_t hexlen,char * dstbuf,size_t dstlen)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 *
strtrim(char * buf,const char * class)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 *
strstrip(char * buf,const char * class)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 *
trim_whitespace(char * buf)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
rand_hash(unsigned char * data,size_t datalen,unsigned char * key,size_t keylen)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
smb_chk_hostaccess(smb_inaddr_t * ipaddr,char * access_list)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
smb_netgroup_match(struct nd_hostservlist * clnames,char * glist,int grc)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
smb_getdataset(const char * path,char * dataset,size_t len)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 *
smb_dlopen(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
smb_dlclose(void * handle)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
smb_getnameinfo(smb_inaddr_t * ip,char * hostname,int hostlen,int flags)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
smb_name_validate_share(const char * sharename)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
smb_name_validate_account(const char * name)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
smb_name_validate_domain(const char * domain)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
smb_name_validate_nbdomain(const char * name)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
smb_name_validate_workgroup(const char * workgroup)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
smb_name_validate_rpath(const char * relpath)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
smb_name_parse(char * arg,char ** account,char ** domain)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
smb_get_txid(void)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