2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
25 #ifdef WITH_NISPLUS_HOME
26 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
28 * The following lines are needed due to buggy include files
29 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
30 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
31 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
32 * an enum in /usr/include/rpcsvc/nis.h.
39 #if defined(GROUP_OBJ)
43 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
45 #include <rpcsvc/nis.h>
47 #else /* !WITH_NISPLUS_HOME */
49 #include "rpcsvc/ypclnt.h"
51 #endif /* WITH_NISPLUS_HOME */
52 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
56 #undef Realloc /* SSLeay defines this and samba has a function of this name */
63 extern int DEBUGLEVEL;
65 int Protocol = PROTOCOL_COREPLUS;
67 /* a default finfo structure to ensure all fields are sensible */
68 file_info def_finfo = {-1,0,0,0,0,0,0,""};
70 /* the client file descriptor */
73 /* this is used by the chaining code */
79 case handling on filenames
81 int case_default = CASE_LOWER;
83 /* the following control case operations - they are put here so the
84 client can link easily */
87 BOOL use_mangled_map = False;
88 BOOL short_case_preserve;
91 fstring remote_machine="";
92 fstring local_machine="";
93 fstring remote_arch="UNKNOWN";
94 static enum remote_arch_types ra_type = RA_UNKNOWN;
95 fstring remote_proto="UNKNOWN";
96 pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;
98 pstring sesssetup_user="";
99 pstring samlogon_user="";
101 BOOL sam_logon_in_ssb = False;
103 pstring global_myname = "";
104 fstring global_myworkgroup = "";
105 char **my_netbios_names;
107 static char *filename_dos(char *path,char *buf);
111 /****************************************************************************
112 find a suitable temporary directory. The result should be copied immediately
113 as it may be overwritten by a subsequent call
114 ****************************************************************************/
118 if ((p = getenv("TMPDIR"))) {
124 /****************************************************************************
125 determine whether we are in the specified group
126 ****************************************************************************/
128 BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
132 if (group == current_gid) return(True);
134 for (i=0;i<ngroups;i++)
135 if (group == groups[i])
142 /****************************************************************************
143 like atoi but gets the value up to the separater character
144 ****************************************************************************/
145 char *Atoic(char *p, int *n, char *c)
147 if (!isdigit((int)*p))
149 DEBUG(5, ("Atoic: malformed number\n"));
155 while ((*p) && isdigit((int)*p))
160 if (strchr(c, *p) == NULL)
162 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
169 /*************************************************************************
170 reads a list of numbers
171 *************************************************************************/
172 char *get_numlist(char *p, uint32 **num, int *count)
176 if (num == NULL || count == NULL)
184 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':')
186 (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
191 (*num)[(*count)] = val;
199 /*******************************************************************
200 copy an IP address from one buffer to another
201 ********************************************************************/
202 void putip(void *dest,void *src)
208 #define TRUNCATE_NETBIOS_NAME 1
210 /*******************************************************************
211 convert, possibly using a stupid microsoft-ism which has destroyed
212 the transport independence of netbios (for CIFS vendors that usually
213 use the Win95-type methods, not for NT to NT communication, which uses
214 DCE/RPC and therefore full-length unicode strings...) a dns name into
217 the netbios name (NOT necessarily null-terminated) is truncated to 15
220 ******************************************************************/
221 char *dns_to_netbios_name(char *dns_name)
223 static char netbios_name[16];
225 StrnCpy(netbios_name, dns_name, 15);
226 netbios_name[15] = 0;
228 #ifdef TRUNCATE_NETBIOS_NAME
229 /* ok. this is because of a stupid microsoft-ism. if the called host
230 name contains a '.', microsoft clients expect you to truncate the
231 netbios name up to and including the '.' this even applies, by
232 mistake, to workgroup (domain) names, which is _really_ daft.
234 for (i = 15; i >= 0; i--)
236 if (netbios_name[i] == '.')
242 #endif /* TRUNCATE_NETBIOS_NAME */
248 /****************************************************************************
249 interpret the weird netbios "name". Return the name type
250 ****************************************************************************/
251 static int name_interpret(char *in,char *out)
254 int len = (*in++) / 2;
258 if (len > 30 || len<1) return(0);
262 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
266 *out = ((in[0]-'A')<<4) + (in[1]-'A');
274 /* Handle any scope names */
277 *out++ = '.'; /* Scope names are separated by periods */
278 len = *(unsigned char *)in++;
279 StrnCpy(out, in, len);
288 /****************************************************************************
289 mangle a name into netbios format
291 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
292 ****************************************************************************/
293 int name_mangle( char *In, char *Out, char name_type )
301 /* Safely copy the input string, In, into buf[]. */
302 (void)memset( buf, 0, 20 );
303 if (strcmp(In,"*") == 0)
306 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
308 /* Place the length of the first field into the output buffer. */
312 /* Now convert the name to the rfc1001/1002 format. */
313 for( i = 0; i < 16; i++ )
315 c = toupper( buf[i] );
316 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
317 p[(i*2)+1] = (c & 0x000F) + 'A';
322 /* Add the scope string. */
323 for( i = 0, len = 0; NULL != scope; i++, len++ )
331 return( name_len(Out) );
343 return( name_len(Out) );
346 /*******************************************************************
347 check if a file exists
348 ********************************************************************/
349 BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
352 if (!sbuf) sbuf = &st;
354 if (sys_stat(fname,sbuf) != 0)
357 return(S_ISREG(sbuf->st_mode));
360 /*******************************************************************
361 check a files mod time
362 ********************************************************************/
363 time_t file_modtime(char *fname)
367 if (sys_stat(fname,&st) != 0)
373 /*******************************************************************
374 check if a directory exists
375 ********************************************************************/
376 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
383 if (sys_stat(dname,st) != 0)
386 ret = S_ISDIR(st->st_mode);
392 /*******************************************************************
393 returns the size in bytes of the named file
394 ********************************************************************/
395 SMB_OFF_T get_file_size(char *file_name)
399 if(sys_stat(file_name,&buf) != 0)
400 return (SMB_OFF_T)-1;
404 /*******************************************************************
405 return a string representing an attribute for a file
406 ********************************************************************/
407 char *attrib_string(uint16 mode)
409 static fstring attrstr;
413 if (mode & aVOLID) fstrcat(attrstr,"V");
414 if (mode & aDIR) fstrcat(attrstr,"D");
415 if (mode & aARCH) fstrcat(attrstr,"A");
416 if (mode & aHIDDEN) fstrcat(attrstr,"H");
417 if (mode & aSYSTEM) fstrcat(attrstr,"S");
418 if (mode & aRONLY) fstrcat(attrstr,"R");
425 /****************************************************************************
426 make a file into unix format
427 ****************************************************************************/
428 void unix_format(char *fname)
430 string_replace(fname,'\\','/');
433 /****************************************************************************
434 make a file into dos format
435 ****************************************************************************/
436 void dos_format(char *fname)
438 string_replace(fname,'/','\\');
441 /*******************************************************************
442 show a smb message structure
443 ********************************************************************/
444 void show_msg(char *buf)
449 if (DEBUGLEVEL < 5) return;
451 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
453 (int)CVAL(buf,smb_com),
454 (int)CVAL(buf,smb_rcls),
455 (int)CVAL(buf,smb_reh),
456 (int)SVAL(buf,smb_err),
457 (int)CVAL(buf,smb_flg),
458 (int)SVAL(buf,smb_flg2)));
459 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
460 (int)SVAL(buf,smb_tid),
461 (int)SVAL(buf,smb_pid),
462 (int)SVAL(buf,smb_uid),
463 (int)SVAL(buf,smb_mid),
464 (int)CVAL(buf,smb_wct)));
466 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
468 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
469 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
472 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
474 DEBUG(5,("smb_bcc=%d\n",bcc));
476 if (DEBUGLEVEL < 10) return;
483 dump_data(10, smb_buf(buf), bcc);
485 /*******************************************************************
486 return the length of an smb packet
487 ********************************************************************/
488 int smb_len(char *buf)
490 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
493 /*******************************************************************
494 set the length of an smb packet
495 ********************************************************************/
496 void _smb_setlen(char *buf,int len)
499 buf[1] = (len&0x10000)>>16;
500 buf[2] = (len&0xFF00)>>8;
504 /*******************************************************************
505 set the length and marker of an smb packet
506 ********************************************************************/
507 void smb_setlen(char *buf,int len)
509 _smb_setlen(buf,len);
517 /*******************************************************************
518 setup the word count and byte count for a smb message
519 ********************************************************************/
520 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
523 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
524 CVAL(buf,smb_wct) = num_words;
525 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
526 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
527 return (smb_size + num_words*2 + num_bytes);
530 /*******************************************************************
531 return the number of smb words
532 ********************************************************************/
533 static int smb_numwords(char *buf)
535 return (CVAL(buf,smb_wct));
538 /*******************************************************************
539 return the size of the smb_buf region of a message
540 ********************************************************************/
541 int smb_buflen(char *buf)
543 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
546 /*******************************************************************
547 return a pointer to the smb_buf data area
548 ********************************************************************/
549 static int smb_buf_ofs(char *buf)
551 return (smb_size + CVAL(buf,smb_wct)*2);
554 /*******************************************************************
555 return a pointer to the smb_buf data area
556 ********************************************************************/
557 char *smb_buf(char *buf)
559 return (buf + smb_buf_ofs(buf));
562 /*******************************************************************
563 return the SMB offset into an SMB buffer
564 ********************************************************************/
565 int smb_offset(char *p,char *buf)
567 return(PTR_DIFF(p,buf+4) + chain_size);
570 /*******************************************************************
571 reduce a file name, removing .. elements.
572 ********************************************************************/
573 void dos_clean_name(char *s)
577 DEBUG(3,("dos_clean_name [%s]\n",s));
579 /* remove any double slashes */
580 all_string_sub(s, "\\\\", "\\", 0);
582 while ((p = strstr(s,"\\..\\")) != NULL)
589 if ((p=strrchr(s,'\\')) != NULL)
596 trim_string(s,NULL,"\\..");
598 all_string_sub(s, "\\.\\", "\\", 0);
601 /*******************************************************************
602 reduce a file name, removing .. elements.
603 ********************************************************************/
604 void unix_clean_name(char *s)
608 DEBUG(3,("unix_clean_name [%s]\n",s));
610 /* remove any double slashes */
611 all_string_sub(s, "//","/", 0);
613 /* Remove leading ./ characters */
614 if(strncmp(s, "./", 2) == 0) {
615 trim_string(s, "./", NULL);
620 while ((p = strstr(s,"/../")) != NULL)
627 if ((p=strrchr(s,'/')) != NULL)
634 trim_string(s,NULL,"/..");
637 /*******************************************************************
638 reduce a file name, removing .. elements and checking that
639 it is below dir in the heirachy. This uses dos_GetWd() and so must be run
640 on the system that has the referenced file system.
642 widelinks are allowed if widelinks is true
643 ********************************************************************/
645 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
655 BOOL relative = (*s != '/');
657 *dir2 = *wd = *base_name = *newname = 0;
662 /* can't have a leading .. */
663 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
665 DEBUG(3,("Illegal file name? (%s)\n",s));
675 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
677 /* remove any double slashes */
678 all_string_sub(s,"//","/",0);
680 pstrcpy(base_name,s);
681 p = strrchr(base_name,'/');
688 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
692 if (dos_ChDir(dir) != 0)
694 DEBUG(0,("couldn't chdir to %s\n",dir));
698 if (!dos_GetWd(dir2))
700 DEBUG(0,("couldn't getwd for %s\n",dir));
705 if (p && (p != base_name))
708 if (strcmp(p+1,".")==0)
710 if (strcmp(p+1,"..")==0)
714 if (dos_ChDir(base_name) != 0)
717 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
721 if (!dos_GetWd(newname))
724 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
728 if (p && (p != base_name))
730 pstrcat(newname,"/");
731 pstrcat(newname,p+1);
735 size_t l = strlen(dir2);
736 if (dir2[l-1] == '/')
739 if (strncmp(newname,dir2,l) != 0)
742 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l));
748 if (newname[l] == '/')
749 pstrcpy(s,newname + l + 1);
751 pstrcpy(s,newname+l);
762 DEBUG(3,("reduced to %s\n",s));
767 /****************************************************************************
769 ****************************************************************************/
770 static void expand_one(char *Mask,int len)
773 while ((p1 = strchr(Mask,'*')) != NULL)
775 int lfill = (len+1) - strlen(Mask);
779 memset(tmp+l1,'?',lfill);
780 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
785 /****************************************************************************
786 parse out a directory name from a path name. Assumes dos style filenames.
787 ****************************************************************************/
788 static void dirname_dos(char *path,char *buf)
790 split_at_last_component(path, buf, '\\', NULL);
794 /****************************************************************************
795 expand a wildcard expression, replacing *s with ?s
796 ****************************************************************************/
797 void expand_mask(char *Mask,BOOL doext)
804 BOOL absolute = (*Mask == '\\');
806 *mbeg = *mext = *dirpart = *filepart = 0;
808 /* parse the directory and filename */
809 if (strchr(Mask,'\\'))
810 dirname_dos(Mask,dirpart);
812 filename_dos(Mask,filepart);
814 pstrcpy(mbeg,filepart);
815 if ((p1 = strchr(mbeg,'.')) != NULL)
825 if (strlen(mbeg) > 8)
827 pstrcpy(mext,mbeg + 8);
833 pstrcpy(mbeg,"????????");
834 if ((*mext == 0) && doext && !hasdot)
837 if (strequal(mbeg,"*") && *mext==0)
845 pstrcpy(Mask,dirpart);
846 if (*dirpart || absolute) pstrcat(Mask,"\\");
851 DEBUG(6,("Mask expanded to [%s]\n",Mask));
856 /****************************************************************************
858 ****************************************************************************/
859 void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
866 if ((mode & aDIR) != 0)
869 memset(buf+1,' ',11);
870 if ((p = strchr(mask2,'.')) != NULL)
873 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
874 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
878 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
880 memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
882 put_dos_date(buf,22,date);
883 SSVAL(buf,26,size & 0xFFFF);
884 SSVAL(buf,28,(size >> 16)&0xFFFF);
885 StrnCpy(buf+30,fname,12);
888 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
892 /*******************************************************************
893 close the low 3 fd's and open dev/null in their place
894 ********************************************************************/
895 void close_low_fds(void)
899 close(0); close(1); close(2);
900 /* try and use up these file descriptors, so silly
901 library routines writing to stdout etc won't cause havoc */
903 fd = sys_open("/dev/null",O_RDWR,0);
904 if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
906 DEBUG(0,("Can't open /dev/null\n"));
910 DEBUG(0,("Didn't get file descriptor %d\n",i));
916 /****************************************************************************
917 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
921 ****************************************************************************/
922 int set_blocking(int fd, BOOL set)
926 #define FLAG_TO_SET O_NONBLOCK
929 #define FLAG_TO_SET O_NDELAY
931 #define FLAG_TO_SET FNDELAY
935 if((val = fcntl(fd, F_GETFL, 0)) == -1)
937 if(set) /* Turn blocking on - ie. clear nonblock flag */
941 return fcntl( fd, F_SETFL, val);
946 /*******************************************************************
947 find the difference in milliseconds between two struct timeval
949 ********************************************************************/
950 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
952 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
953 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
958 /****************************************************************************
959 transfer some data between two fd's
960 ****************************************************************************/
961 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
963 static char *buf=NULL;
968 DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
971 size = lp_readsize();
972 size = MAX(size,1024);
975 while (!buf && size>0) {
976 buf = (char *)Realloc(buf,size+8);
981 DEBUG(0,("Can't allocate transfer buffer!\n"));
985 abuf = buf + (align%8);
992 int s = (int)MIN(n,(SMB_OFF_T)size);
997 if (header && (headlen >= MIN(s,1024))) {
1007 if (header && headlen > 0)
1009 ret = MIN(headlen,size);
1010 memcpy(buf1,header,ret);
1013 if (headlen <= 0) header = NULL;
1017 ret += read(infd,buf1+ret,s-ret);
1021 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
1022 if (ret2 > 0) total += ret2;
1023 /* if we can't write then dump excess data */
1025 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
1027 if (ret <= 0 || ret2 != ret)
1036 /****************************************************************************
1037 find a pointer to a netbios name
1038 ****************************************************************************/
1039 static char *name_ptr(char *buf,int ofs)
1041 unsigned char c = *(unsigned char *)(buf+ofs);
1043 if ((c & 0xC0) == 0xC0)
1045 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1046 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1053 /****************************************************************************
1054 extract a netbios name from a buf
1055 ****************************************************************************/
1056 int name_extract(char *buf,int ofs,char *name)
1058 char *p = name_ptr(buf,ofs);
1059 int d = PTR_DIFF(p,buf+ofs);
1061 if (d < -50 || d > 50) return(0);
1062 return(name_interpret(p,name));
1065 /****************************************************************************
1066 return the total storage length of a mangled name
1067 ****************************************************************************/
1068 int name_len(char *s1)
1070 /* NOTE: this argument _must_ be unsigned */
1071 unsigned char *s = (unsigned char *)s1;
1074 /* If the two high bits of the byte are set, return 2. */
1075 if (0xC0 == (*s & 0xC0))
1078 /* Add up the length bytes. */
1079 for (len = 1; (*s); s += (*s) + 1) {
1081 SMB_ASSERT(len < 80);
1088 /*******************************************************************
1089 sleep for a specified number of milliseconds
1090 ********************************************************************/
1094 struct timeval tval,t1,t2;
1101 tval.tv_sec = (t-tdiff)/1000;
1102 tval.tv_usec = 1000*((t-tdiff)%1000);
1106 sys_select(0,&fds,&tval);
1109 tdiff = TvalDiff(&t1,&t2);
1114 /*********************************************************
1115 * Recursive routine that is called by unix_mask_match.
1116 * Does the actual matching. This is the 'original code'
1117 * used by the unix matcher.
1118 *********************************************************/
1120 BOOL unix_do_match(char *str, char *regexp, BOOL case_sig)
1124 for( p = regexp; *p && *str; ) {
1131 /* Look for a character matching
1132 the one after the '*' */
1135 return True; /* Automatic match */
1137 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
1139 if(unix_do_match(str,p,case_sig))
1153 if(toupper(*str) != toupper(*p))
1163 if (!*p && str[0] == '.' && str[1] == 0)
1166 if (!*str && *p == '?')
1168 while (*p == '?') p++;
1172 if(!*str && (*p == '*' && p[1] == '\0'))
1178 /*********************************************************
1179 * Routine to match a given string with a regexp - uses
1180 * simplified regexp that takes * and ? only. Case can be
1181 * significant or not.
1182 * This is the 'original code' used by the unix matcher.
1183 *********************************************************/
1185 static BOOL unix_mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2)
1189 fstring ebase,eext,sbase,sext;
1193 /* Make local copies of str and regexp */
1194 StrnCpy(p1,regexp,sizeof(pstring)-1);
1195 StrnCpy(p2,str,sizeof(pstring)-1);
1197 if (!strchr(p2,'.')) {
1201 /* Remove any *? and ** as they are meaningless */
1202 for(p = p1; *p; p++)
1203 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
1204 (void)pstrcpy( &p[1], &p[2]);
1206 if (strequal(p1,"*")) return(True);
1208 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
1214 if ((p=strrchr(p1,'.'))) {
1223 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
1233 matched = unix_do_match(sbase,ebase,case_sig) &&
1234 (trans2 || unix_do_match(sext,eext,case_sig));
1236 DEBUG(8,("unix_mask_match returning %d\n", matched));
1241 /*********************************************************
1242 * Recursive routine that is called by mask_match.
1243 * Does the actual matching. Returns True if matched,
1244 * False if failed. This is the 'new' NT style matcher.
1245 * The win9x_semantics parameter is needed as Win9x matching
1246 * is *actually different*. In Win9x, trailing '?' characters
1247 * will only match the *exact* number of characters. Under
1248 * DOS and NT they match any number. This makes no
1250 *********************************************************/
1252 static BOOL do_match(char *str, char *regexp, int case_sig, BOOL win9x_semantics)
1256 for( p = regexp; *p && *str; ) {
1263 /* Look for a character matching
1264 the one after the '*' */
1267 return True; /* Automatic match */
1269 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
1271 /* Now eat all characters that match, as
1272 we want the *last* character to match. */
1273 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
1275 str--; /* We've eaten the match char after the '*' */
1276 if(do_match(str,p,case_sig,win9x_semantics)) {
1293 if(toupper(*str) != toupper(*p)) {
1305 if (!*p && str[0] == '.' && str[1] == 0) {
1309 if (!win9x_semantics) {
1310 if (!*str && *p == '?') {
1317 if(!*str && (*p == '*' && p[1] == '\0')) {
1324 /*********************************************************
1325 * Routine to check if a given string matches exactly.
1326 * Case can be significant or not.
1327 **********************************************************/
1329 BOOL exact_match(char *str, char *regexp, BOOL case_sig)
1331 return ((case_sig?strcmp(str,regexp):strcasecmp(str,regexp)) == 0);
1334 /*********************************************************
1335 * Routine to match a given string with a regexp - uses
1336 * simplified regexp that takes * and ? only. Case can be
1337 * significant or not.
1338 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
1339 * This is the new 'NT style' matcher.
1340 *********************************************************/
1342 BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2)
1345 pstring t_pattern, t_filename, te_pattern, te_filename;
1346 fstring ebase,eext,sbase,sext;
1347 BOOL matched = False;
1348 BOOL win9x_semantics = (get_remote_arch() == RA_WIN95) && trans2;
1350 /* special case - if it is exactly the same then it always matches! */
1351 if(exact_match(str, regexp, case_sig))
1354 /* Make local copies of str and regexp */
1355 pstrcpy(t_pattern,regexp);
1356 pstrcpy(t_filename,str);
1360 /* a special case for 16 bit apps */
1361 if (strequal(t_pattern,"????????.???"))
1362 pstrcpy(t_pattern,"*");
1366 * Handle broken clients that send us old 8.3 format.
1368 pstring_sub(t_pattern,"????????","*");
1369 pstring_sub(t_pattern,".???",".*");
1375 * Not sure if this is a good idea. JRA.
1377 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
1382 if (!strchr(t_filename,'.')) {
1383 pstrcat(t_filename,".");
1387 /* Remove any *? and ** as they are meaningless */
1388 pstring_sub(t_pattern, "*?", "*");
1389 pstring_sub(t_pattern, "**", "*");
1391 if (strequal(t_pattern,"*"))
1394 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
1398 * Match each component of the regexp, split up by '.'
1401 char *fp, *rp, *cp2, *cp1;
1402 BOOL last_wcard_was_star = False;
1403 int num_path_components, num_regexp_components;
1405 pstrcpy(te_pattern,t_pattern);
1406 pstrcpy(te_filename,t_filename);
1408 * Remove multiple "*." patterns.
1410 pstring_sub(te_pattern, "*.*.", "*.");
1411 num_regexp_components = count_chars(te_pattern, '.');
1412 num_path_components = count_chars(te_filename, '.');
1415 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
1417 if(num_regexp_components == 0)
1418 matched = do_match( te_filename, te_pattern, case_sig, win9x_semantics);
1420 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
1421 fp = strchr(cp2, '.');
1424 rp = strchr(cp1, '.');
1428 if(cp1[0] && cp1[strlen(cp1)-1] == '*')
1429 last_wcard_was_star = True;
1431 last_wcard_was_star = False;
1433 if(!do_match(cp2, cp1, case_sig, win9x_semantics))
1437 * Ugly ! Special case for Win9x *only*. If filename is XXXX and pattern extension
1438 * is '*' or all '?' then disallow match.
1441 if (win9x_semantics) {
1442 if (*cp2 == '\0' && str_is_all(cp1, '?'))
1446 cp1 = rp ? rp + 1 : NULL;
1447 cp2 = fp ? fp + 1 : "";
1449 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
1450 /* Eat the extra path components. */
1453 for(i = 0; i < num_path_components - num_regexp_components; i++) {
1454 fp = strchr(cp2, '.');
1458 if((cp1 != NULL) && do_match( cp2, cp1, case_sig, win9x_semantics)) {
1459 cp2 = fp ? fp + 1 : "";
1462 cp2 = fp ? fp + 1 : "";
1464 num_path_components -= i;
1467 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
1472 /* -------------------------------------------------
1473 * Behaviour of Win95
1474 * for 8.3 filenames and 8.3 Wildcards
1475 * -------------------------------------------------
1477 if (strequal (t_filename, ".")) {
1479 * Patterns: *.* *. ?. ? ????????.??? are valid.
1482 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
1483 strequal(t_pattern, "????????.???") ||
1484 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
1486 } else if (strequal (t_filename, "..")) {
1488 * Patterns: *.* *. ?. ? *.? ????????.??? are valid.
1491 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
1492 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
1493 strequal(t_pattern, "????????.???") ||
1494 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
1498 if ((p = strrchr (t_pattern, '.'))) {
1500 * Wildcard has a suffix.
1503 fstrcpy (ebase, t_pattern);
1505 fstrcpy (eext, p + 1);
1507 /* pattern ends in DOT: treat as if there is no DOT */
1509 if (strequal (ebase, "*"))
1514 * No suffix for wildcard.
1516 fstrcpy (ebase, t_pattern);
1520 p = strrchr (t_filename, '.');
1521 if (p && (p[1] == 0) ) {
1523 * Filename has an extension of '.' only.
1525 *p = 0; /* nuke dot at end of string */
1526 p = 0; /* and treat it as if there is no extension */
1531 * Filename has an extension.
1534 fstrcpy (sbase, t_filename);
1535 fstrcpy (sext, p + 1);
1537 matched = do_match(sbase, ebase, case_sig, False)
1538 && do_match(sext, eext, case_sig, False);
1540 /* pattern has no extension */
1541 /* Really: match complete filename with pattern ??? means exactly 3 chars */
1542 matched = do_match(str, ebase, case_sig, False);
1546 * Filename has no extension.
1548 fstrcpy (sbase, t_filename);
1551 /* pattern has extension */
1552 matched = do_match(sbase, ebase, case_sig, False)
1553 && do_match(sext, eext, case_sig, False);
1556 matched = do_match(sbase, ebase, case_sig, False);
1557 #ifdef EMULATE_WEIRD_W95_MATCHING
1559 * Even Microsoft has some problems
1560 * Behaviour Win95 -> local disk
1561 * is different from Win95 -> smb drive from Nt 4.0
1562 * This branch would reflect the Win95 local disk behaviour
1565 /* a? matches aa and a in w95 */
1566 fstrcat (sbase, ".");
1567 matched = do_match(sbase, ebase, case_sig, False);
1575 DEBUG(8,("mask_match returning %d\n", matched));
1580 /****************************************************************************
1581 become a daemon, discarding the controlling terminal
1582 ****************************************************************************/
1583 void become_daemon(void)
1589 /* detach from the terminal */
1592 #elif defined(TIOCNOTTY)
1594 int i = sys_open("/dev/tty", O_RDWR, 0);
1596 ioctl(i, (int) TIOCNOTTY, (char *)0);
1600 #endif /* HAVE_SETSID */
1602 /* Close fd's 0,1,2. Needed if started by rsh */
1607 /****************************************************************************
1608 put up a yes/no prompt
1609 ****************************************************************************/
1615 if (!fgets(ans,sizeof(ans)-1,stdin))
1618 if (*ans == 'y' || *ans == 'Y')
1624 /****************************************************************************
1625 set the length of a file from a filedescriptor.
1626 Returns 0 on success, -1 on failure.
1627 ****************************************************************************/
1629 int set_filelen(int fd, SMB_OFF_T len)
1631 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1632 extend a file with ftruncate. Provide alternate implementation
1635 #ifdef HAVE_FTRUNCATE_EXTEND
1636 return sys_ftruncate(fd, len);
1640 SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
1644 /* Do an fstat to see if the file is longer than
1645 the requested size (call ftruncate),
1646 or shorter, in which case seek to len - 1 and write 1
1648 if(sys_fstat(fd, &st)<0)
1652 if (S_ISFIFO(st.st_mode))
1656 if(st.st_size == len)
1658 if(st.st_size > len)
1659 return sys_ftruncate(fd, len);
1661 if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
1663 if(write(fd, &c, 1)!=1)
1665 /* Seek to where we were */
1666 if(sys_lseek(fd, currpos, SEEK_SET) != currpos)
1674 /****************************************************************************
1675 this is a version of setbuffer() for those machines that only have setvbuf
1676 ****************************************************************************/
1677 void setbuffer(FILE *f,char *buf,int bufsize)
1679 setvbuf(f,buf,_IOFBF,bufsize);
1684 /****************************************************************************
1685 parse out a filename from a path name. Assumes dos style filenames.
1686 ****************************************************************************/
1687 static char *filename_dos(char *path,char *buf)
1689 char *p = strrchr(path,'\\');
1701 /****************************************************************************
1702 expand a pointer to be a particular size
1703 ****************************************************************************/
1704 void *Realloc(void *p,size_t size)
1710 DEBUG(5,("Realloc asked for 0 bytes\n"));
1715 ret = (void *)malloc(size);
1717 ret = (void *)realloc(p,size);
1722 smb_mem_write_info(ret, dbf);
1727 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1733 /****************************************************************************
1734 get my own name and IP
1735 ****************************************************************************/
1736 BOOL get_myname(char *my_name)
1742 /* get my host name */
1743 if (gethostname(hostname, sizeof(hostname)) == -1) {
1744 DEBUG(0,("gethostname failed\n"));
1748 /* Ensure null termination. */
1749 hostname[sizeof(hostname)-1] = '\0';
1752 /* split off any parts after an initial . */
1753 char *p = strchr(hostname,'.');
1756 fstrcpy(my_name,hostname);
1763 /****************************************************************************
1764 true if two IP addresses are equal
1765 ****************************************************************************/
1766 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
1768 return ip1.s_addr == ip2.s_addr;
1772 /****************************************************************************
1773 interpret a protocol description string, with a default
1774 ****************************************************************************/
1775 int interpret_protocol(char *str,int def)
1777 if (strequal(str,"NT1"))
1778 return(PROTOCOL_NT1);
1779 if (strequal(str,"LANMAN2"))
1780 return(PROTOCOL_LANMAN2);
1781 if (strequal(str,"LANMAN1"))
1782 return(PROTOCOL_LANMAN1);
1783 if (strequal(str,"CORE"))
1784 return(PROTOCOL_CORE);
1785 if (strequal(str,"COREPLUS"))
1786 return(PROTOCOL_COREPLUS);
1787 if (strequal(str,"CORE+"))
1788 return(PROTOCOL_COREPLUS);
1790 DEBUG(0,("Unrecognised protocol level %s\n",str));
1795 /****************************************************************************
1796 Return true if a string could be a pure IP address.
1797 ****************************************************************************/
1799 BOOL is_ipaddress(const char *str)
1801 BOOL pure_address = True;
1804 for (i=0; pure_address && str[i]; i++)
1805 if (!(isdigit((int)str[i]) || str[i] == '.'))
1806 pure_address = False;
1808 /* Check that a pure number is not misinterpreted as an IP */
1809 pure_address = pure_address && (strchr(str, '.') != NULL);
1811 return pure_address;
1814 /****************************************************************************
1815 interpret an internet address or name into an IP address in 4 byte form
1816 ****************************************************************************/
1818 uint32 interpret_addr(char *str)
1823 if (strcmp(str,"0.0.0.0") == 0) return(0);
1824 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
1826 /* if it's in the form of an IP address then get the lib to interpret it */
1827 if (is_ipaddress(str)) {
1828 res = inet_addr(str);
1830 /* otherwise assume it's a network name of some sort and use
1832 if ((hp = Get_Hostbyname(str)) == 0) {
1833 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
1836 if(hp->h_addr == NULL) {
1837 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
1840 putip((char *)&res,(char *)hp->h_addr);
1843 if (res == (uint32)-1) return(0);
1848 /*******************************************************************
1849 a convenient addition to interpret_addr()
1850 ******************************************************************/
1851 struct in_addr *interpret_addr2(char *str)
1853 static struct in_addr ret;
1854 uint32 a = interpret_addr(str);
1859 /*******************************************************************
1860 check if an IP is the 0.0.0.0
1861 ******************************************************************/
1862 BOOL zero_ip(struct in_addr ip)
1865 putip((char *)&a,(char *)&ip);
1870 /*******************************************************************
1871 matchname - determine if host name matches IP address
1872 ******************************************************************/
1873 BOOL matchname(char *remotehost,struct in_addr addr)
1878 if ((hp = Get_Hostbyname(remotehost)) == 0) {
1879 DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost));
1884 * Make sure that gethostbyname() returns the "correct" host name.
1885 * Unfortunately, gethostbyname("localhost") sometimes yields
1886 * "localhost.domain". Since the latter host name comes from the
1887 * local DNS, we just have to trust it (all bets are off if the local
1888 * DNS is perverted). We always check the address list, though.
1891 if (strcasecmp(remotehost, hp->h_name)
1892 && strcasecmp(remotehost, "localhost")) {
1893 DEBUG(0,("host name/name mismatch: %s != %s\n",
1894 remotehost, hp->h_name));
1898 /* Look up the host address in the address list we just got. */
1899 for (i = 0; hp->h_addr_list[i]; i++) {
1900 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
1905 * The host name does not map to the original host address. Perhaps
1906 * someone has compromised a name server. More likely someone botched
1907 * it, but that could be dangerous, too.
1910 DEBUG(0,("host name/address mismatch: %s != %s\n",
1911 inet_ntoa(addr), hp->h_name));
1916 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1917 /******************************************************************
1918 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1919 Based on a fix from <Thomas.Hepper@icem.de>.
1920 *******************************************************************/
1922 static void strip_mount_options( pstring *str)
1927 while(*p && !isspace(*p))
1929 while(*p && isspace(*p))
1934 pstrcpy(tmp_str, p);
1935 pstrcpy(*str, tmp_str);
1940 /*******************************************************************
1941 Patch from jkf@soton.ac.uk
1942 Split Luke's automount_server into YP lookup and string splitter
1943 so can easily implement automount_path().
1944 As we may end up doing both, cache the last YP result.
1945 *******************************************************************/
1947 #ifdef WITH_NISPLUS_HOME
1948 static char *automount_lookup(char *user_name)
1950 static fstring last_key = "";
1951 static pstring last_value = "";
1953 char *nis_map = (char *)lp_nis_home_map_name();
1955 char nis_domain[NIS_MAXNAMELEN + 1];
1956 char buffer[NIS_MAXATTRVAL + 1];
1961 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
1962 nis_domain[NIS_MAXNAMELEN] = '\0';
1964 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
1966 if (strcmp(user_name, last_key))
1968 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
1969 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1971 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
1973 if (result->status != NIS_SUCCESS)
1975 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1976 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1980 object = result->objects.objects_val;
1981 if (object->zo_data.zo_type == ENTRY_OBJ)
1983 entry = &object->zo_data.objdata_u.en_data;
1984 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1985 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1987 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1988 pstring_sub(last_value, "&", user_name);
1989 fstrcpy(last_key, user_name);
1993 nis_freeresult(result);
1996 strip_mount_options(&last_value);
1998 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
2001 #else /* WITH_NISPLUS_HOME */
2002 static char *automount_lookup(char *user_name)
2004 static fstring last_key = "";
2005 static pstring last_value = "";
2007 int nis_error; /* returned by yp all functions */
2008 char *nis_result; /* yp_match inits this */
2009 int nis_result_len; /* and set this */
2010 char *nis_domain; /* yp_get_default_domain inits this */
2011 char *nis_map = (char *)lp_nis_home_map_name();
2013 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
2015 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
2019 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
2021 if (!strcmp(user_name, last_key))
2023 nis_result = last_value;
2024 nis_result_len = strlen(last_value);
2029 if ((nis_error = yp_match(nis_domain, nis_map,
2030 user_name, strlen(user_name),
2031 &nis_result, &nis_result_len)) != 0)
2033 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
2034 yperr_string(nis_error), user_name, nis_map));
2036 if (!nis_error && nis_result_len >= sizeof(pstring))
2038 nis_result_len = sizeof(pstring)-1;
2040 fstrcpy(last_key, user_name);
2041 strncpy(last_value, nis_result, nis_result_len);
2042 last_value[nis_result_len] = '\0';
2045 strip_mount_options(&last_value);
2047 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
2050 #endif /* WITH_NISPLUS_HOME */
2053 /*******************************************************************
2054 Patch from jkf@soton.ac.uk
2055 This is Luke's original function with the NIS lookup code
2056 moved out to a separate function.
2057 *******************************************************************/
2058 static char *automount_server(char *user_name)
2060 static pstring server_name;
2062 /* use the local machine name as the default */
2063 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2064 pstrcpy(server_name, local_machine);
2066 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2068 if (lp_nis_home_map())
2070 int home_server_len;
2071 char *automount_value = automount_lookup(user_name);
2072 home_server_len = strcspn(automount_value,":");
2073 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
2074 if (home_server_len > sizeof(pstring))
2076 home_server_len = sizeof(pstring);
2078 strncpy(server_name, automount_value, home_server_len);
2079 server_name[home_server_len] = '\0';
2083 DEBUG(4,("Home server: %s\n", server_name));
2088 /*******************************************************************
2089 Patch from jkf@soton.ac.uk
2090 Added this to implement %p (NIS auto-map version of %H)
2091 *******************************************************************/
2092 static char *automount_path(char *user_name)
2094 static pstring server_path;
2096 /* use the passwd entry as the default */
2097 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2098 /* pstrcpy() copes with get_user_home_dir() returning NULL */
2099 pstrcpy(server_path, get_user_home_dir(user_name));
2101 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2103 if (lp_nis_home_map())
2105 char *home_path_start;
2106 char *automount_value = automount_lookup(user_name);
2107 home_path_start = strchr(automount_value,':');
2108 if (home_path_start != NULL)
2110 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
2111 home_path_start?(home_path_start+1):""));
2112 pstrcpy(server_path, home_path_start+1);
2117 DEBUG(4,("Home server path: %s\n", server_path));
2122 /*******************************************************************
2123 Given a pointer to a %$(NAME) expand it as an environment variable.
2124 Return the number of characters by which the pointer should be advanced.
2125 Based on code by Branko Cibej <branko.cibej@hermes.si>
2126 When this is called p points at the '%' character.
2127 ********************************************************************/
2129 static size_t expand_env_var(char *p, int len)
2143 * Look for the terminating ')'.
2146 if ((q = strchr(p,')')) == NULL) {
2147 DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
2152 * Extract the name from within the %$(NAME) string.
2156 copylen = MIN((q-r),(sizeof(envname)-1));
2157 strncpy(envname,r,copylen);
2158 envname[copylen] = '\0';
2160 if ((envval = getenv(envname)) == NULL) {
2161 DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
2166 * Copy the full %$(NAME) into envname so it
2170 copylen = MIN((q+1-p),(sizeof(envname)-1));
2171 strncpy(envname,p,copylen);
2172 envname[copylen] = '\0';
2173 string_sub(p,envname,envval,len);
2174 return 0; /* Allow the environment contents to be parsed. */
2177 /*******************************************************************
2178 Substitute strings with useful parameters.
2179 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
2180 Paul Rippin <pr3245@nopc.eurostat.cec.be>.
2181 ********************************************************************/
2183 void standard_sub_basic(char *str)
2187 struct passwd *pass;
2188 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
2190 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
2192 int l = sizeof(pstring) - (int)(p-str);
2195 DEBUG(0,("ERROR: string overflow by %d in standard_sub_basic(%.50s)\n",
2205 if ((pass = Get_Pwnam(username,False))!=NULL) {
2206 string_sub(p,"%G",gidtoname(pass->pw_gid),l);
2212 case 'N' : string_sub(p,"%N", automount_server(username),l); break;
2213 case 'I' : string_sub(p,"%I", client_addr(Client),l); break;
2214 case 'L' : string_sub(p,"%L", local_machine,l); break;
2215 case 'M' : string_sub(p,"%M", client_name(Client),l); break;
2216 case 'R' : string_sub(p,"%R", remote_proto,l); break;
2217 case 'T' : string_sub(p,"%T", timestring(False),l); break;
2218 case 'U' : string_sub(p,"%U", username,l); break;
2219 case 'a' : string_sub(p,"%a", remote_arch,l); break;
2222 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
2223 string_sub(p,"%d", pidstr,l);
2226 case 'h' : string_sub(p,"%h", myhostname(),l); break;
2227 case 'm' : string_sub(p,"%m", remote_machine,l); break;
2228 case 'v' : string_sub(p,"%v", VERSION,l); break;
2229 case '$' : p += expand_env_var(p,l); break; /* Expand environment variables */
2230 case '\0': p++; break; /* don't run off end if last character is % */
2231 default : p+=2; break;
2238 /****************************************************************************
2239 Do some standard substitutions in a string.
2240 ****************************************************************************/
2242 void standard_sub(connection_struct *conn,char *str)
2246 for (s=str; (p=strchr(s, '%'));s=p) {
2247 int l = sizeof(pstring) - (int)(p-str);
2251 if ((home = get_user_home_dir(conn->user))) {
2252 string_sub(p,"%H",home,l);
2259 string_sub(p,"%P",conn->connectpath,l);
2264 lp_servicename(SNUM(conn)),l);
2269 gidtoname(conn->gid),l);
2272 string_sub(p,"%u",conn->user,l);
2275 /* Patch from jkf@soton.ac.uk Left the %N (NIS
2276 * server name) in standard_sub_basic as it is
2277 * a feature for logon servers, hence uses the
2278 * username. The %p (NIS server path) code is
2279 * here as it is used instead of the default
2280 * "path =" string in [homes] and so needs the
2281 * service name, not the username. */
2284 automount_path(lp_servicename(SNUM(conn))),l);
2288 break; /* don't run off the end of the string
2296 standard_sub_basic(str);
2301 /*******************************************************************
2302 are two IPs on the same subnet?
2303 ********************************************************************/
2304 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
2306 uint32 net1,net2,nmask;
2308 nmask = ntohl(mask.s_addr);
2309 net1 = ntohl(ip1.s_addr);
2310 net2 = ntohl(ip2.s_addr);
2312 return((net1 & nmask) == (net2 & nmask));
2316 /****************************************************************************
2317 a wrapper for gethostbyname() that tries with all lower and all upper case
2318 if the initial name fails
2319 ****************************************************************************/
2320 struct hostent *Get_Hostbyname(const char *name)
2322 char *name2 = strdup(name);
2323 struct hostent *ret;
2327 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
2333 * This next test is redundent and causes some systems (with
2334 * broken isalnum() calls) problems.
2339 if (!isalnum(*name2))
2346 ret = sys_gethostbyname(name2);
2353 /* try with all lowercase */
2355 ret = sys_gethostbyname(name2);
2362 /* try with all uppercase */
2364 ret = sys_gethostbyname(name2);
2371 /* nothing works :-( */
2377 /****************************************************************************
2378 check if a process exists. Does this work on all unixes?
2379 ****************************************************************************/
2381 BOOL process_exists(pid_t pid)
2383 return(kill(pid,0) == 0 || errno != ESRCH);
2387 /*******************************************************************
2388 turn a uid into a user name
2389 ********************************************************************/
2390 char *uidtoname(uid_t uid)
2392 static char name[40];
2393 struct passwd *pass = sys_getpwuid(uid);
2394 if (pass) return(pass->pw_name);
2395 slprintf(name, sizeof(name) - 1, "%d",(int)uid);
2400 /*******************************************************************
2401 turn a gid into a group name
2402 ********************************************************************/
2404 char *gidtoname(gid_t gid)
2406 static char name[40];
2407 struct group *grp = getgrgid(gid);
2408 if (grp) return(grp->gr_name);
2409 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
2413 /*******************************************************************
2414 turn a user name into a uid
2415 ********************************************************************/
2416 uid_t nametouid(const char *name)
2418 struct passwd *pass;
2422 u = strtol(name, &p, 0);
2423 if (p != name) return u;
2425 pass = sys_getpwnam(name);
2426 if (pass) return(pass->pw_uid);
2430 /*******************************************************************
2431 turn a group name into a gid
2432 ********************************************************************/
2433 gid_t nametogid(const char *name)
2439 g = strtol(name, &p, 0);
2440 if (p != name) return g;
2442 grp = getgrnam(name);
2443 if (grp) return(grp->gr_gid);
2447 /*******************************************************************
2448 something really nasty happened - panic!
2449 ********************************************************************/
2450 void smb_panic(char *why)
2452 char *cmd = lp_panic_action();
2456 DEBUG(0,("PANIC: %s\n", why));
2462 /*******************************************************************
2463 a readdir wrapper which just returns the file name
2464 ********************************************************************/
2465 char *readdirname(DIR *p)
2467 SMB_STRUCT_DIRENT *ptr;
2470 if (!p) return(NULL);
2472 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
2473 if (!ptr) return(NULL);
2475 dname = ptr->d_name;
2478 if (telldir(p) < 0) return(NULL);
2481 #ifdef HAVE_BROKEN_READDIR
2482 /* using /usr/ucb/cc is BAD */
2488 memcpy(buf, dname, NAMLEN(ptr)+1);
2495 /*******************************************************************
2496 Utility function used to decide if the last component
2497 of a path matches a (possibly wildcarded) entry in a namelist.
2498 ********************************************************************/
2500 BOOL is_in_path(char *name, name_compare_entry *namelist)
2502 pstring last_component;
2505 DEBUG(8, ("is_in_path: %s\n", name));
2507 /* if we have no list it's obviously not in the path */
2508 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
2510 DEBUG(8,("is_in_path: no name list.\n"));
2514 /* Get the last component of the unix name. */
2515 p = strrchr(name, '/');
2516 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
2517 last_component[sizeof(last_component)-1] = '\0';
2519 for(; namelist->name != NULL; namelist++)
2521 if(namelist->is_wild)
2524 * Look for a wildcard match. Use the old
2525 * 'unix style' mask match, rather than the
2528 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
2530 DEBUG(8,("is_in_path: mask match succeeded\n"));
2536 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
2537 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
2539 DEBUG(8,("is_in_path: match succeeded\n"));
2544 DEBUG(8,("is_in_path: match not found\n"));
2549 /*******************************************************************
2550 Strip a '/' separated list into an array of
2551 name_compare_enties structures suitable for
2552 passing to is_in_path(). We do this for
2553 speed so we can pre-parse all the names in the list
2554 and don't do it for each call to is_in_path().
2555 namelist is modified here and is assumed to be
2556 a copy owned by the caller.
2557 We also check if the entry contains a wildcard to
2558 remove a potentially expensive call to mask_match
2560 ********************************************************************/
2562 void set_namearray(name_compare_entry **ppname_array, char *namelist)
2565 char *nameptr = namelist;
2566 int num_entries = 0;
2569 (*ppname_array) = NULL;
2571 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
2574 /* We need to make two passes over the string. The
2575 first to count the number of elements, the second
2580 if ( *nameptr == '/' )
2582 /* cope with multiple (useless) /s) */
2586 /* find the next / */
2587 name_end = strchr(nameptr, '/');
2589 /* oops - the last check for a / didn't find one. */
2590 if (name_end == NULL)
2593 /* next segment please */
2594 nameptr = name_end + 1;
2598 if(num_entries == 0)
2601 if(( (*ppname_array) = (name_compare_entry *)malloc(
2602 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
2604 DEBUG(0,("set_namearray: malloc fail\n"));
2608 /* Now copy out the names */
2613 if ( *nameptr == '/' )
2615 /* cope with multiple (useless) /s) */
2619 /* find the next / */
2620 if ((name_end = strchr(nameptr, '/')) != NULL)
2625 /* oops - the last check for a / didn't find one. */
2626 if(name_end == NULL)
2629 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
2630 (strchr( nameptr, '*')!=NULL));
2631 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
2633 DEBUG(0,("set_namearray: malloc fail (1)\n"));
2637 /* next segment please */
2638 nameptr = name_end + 1;
2642 (*ppname_array)[i].name = NULL;
2647 /****************************************************************************
2648 routine to free a namearray.
2649 ****************************************************************************/
2651 void free_namearray(name_compare_entry *name_array)
2656 if(name_array->name != NULL)
2657 free(name_array->name);
2659 free((char *)name_array);
2662 /****************************************************************************
2663 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
2664 ****************************************************************************/
2666 uint32 map_lock_offset(uint32 high, uint32 low)
2670 uint32 highcopy = high;
2673 * Try and find out how many significant bits there are in high.
2676 for(i = 0; highcopy; i++)
2680 * We use 31 bits not 32 here as POSIX
2681 * lock offsets may not be negative.
2684 mask = (~0) << (31 - i);
2687 return 0; /* Fail. */
2694 /****************************************************************************
2695 routine to do file locking
2696 ****************************************************************************/
2698 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2701 SMB_STRUCT_FLOCK lock;
2703 #if defined(LARGE_SMB_OFF_T)
2705 * In the 64 bit locking case we store the original
2706 * values in case we have to map to a 32 bit lock on
2707 * a filesystem that doesn't support 64 bit locks.
2709 SMB_OFF_T orig_offset = offset;
2710 SMB_OFF_T orig_count = count;
2711 #endif /* LARGE_SMB_OFF_T */
2713 if(lp_ole_locking_compat()) {
2714 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
2715 SMB_OFF_T mask = (mask2<<2);
2717 /* make sure the count is reasonable, we might kill the lockd otherwise */
2720 /* the offset is often strange - remove 2 of its bits if either of
2721 the top two bits are set. Shift the top ones by two bits. This
2722 still allows OLE2 apps to operate, but should stop lockd from
2724 if ((offset & mask) != 0)
2725 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
2727 SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
2728 SMB_OFF_T mask = (mask2<<1);
2729 SMB_OFF_T neg_mask = ~mask;
2731 /* interpret negative counts as large numbers */
2735 /* no negative offsets */
2739 /* count + offset must be in range */
2740 while ((offset < 0 || (offset + count < 0)) && mask)
2743 mask = ((mask >> 1) & neg_mask);
2747 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
2750 lock.l_whence = SEEK_SET;
2751 lock.l_start = offset;
2757 ret = fcntl(fd,op,&lock);
2762 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
2763 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
2764 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
2766 /* 32 bit NFS file system, retry with smaller offset */
2768 lock.l_len = count & 0x7fffffff;
2769 ret = fcntl(fd,op,&lock);
2773 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
2776 if (op == SMB_F_GETLK)
2779 (lock.l_type != F_UNLCK) &&
2780 (lock.l_pid != 0) &&
2781 (lock.l_pid != getpid()))
2783 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
2787 /* it must be not locked or locked by me */
2791 /* a lock set or unset */
2794 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2795 (double)offset,(double)count,op,type,strerror(errno)));
2797 /* perhaps it doesn't support this sort of locking?? */
2798 if (errno == EINVAL)
2801 #if defined(LARGE_SMB_OFF_T)
2804 * Ok - if we get here then we have a 64 bit lock request
2805 * that has returned EINVAL. Try and map to 31 bits for offset
2806 * and length and try again. This may happen if a filesystem
2807 * doesn't support 64 bit offsets (efs/ufs) although the underlying
2810 uint32 off_low = (orig_offset & 0xFFFFFFFF);
2811 uint32 off_high = ((orig_offset >> 32) & 0xFFFFFFFF);
2813 lock.l_len = (orig_count & 0x7FFFFFFF);
2814 lock.l_start = (SMB_OFF_T)map_lock_offset(off_high, off_low);
2815 ret = fcntl(fd,op,&lock);
2818 if (errno == EINVAL)
2820 DEBUG(3,("locking not supported? returning True\n"));
2825 DEBUG(3,("64 -> 32 bit modified lock call successful\n"));
2828 #else /* LARGE_SMB_OFF_T */
2829 DEBUG(3,("locking not supported? returning True\n"));
2831 #endif /* LARGE_SMB_OFF_T */
2837 /* everything went OK */
2838 DEBUG(8,("Lock call successful\n"));
2846 /*******************************************************************
2847 is the name specified one of my netbios names
2848 returns true is it is equal, false otherwise
2849 ********************************************************************/
2850 BOOL is_myname(char *s)
2855 for (n=0; my_netbios_names[n]; n++) {
2856 if (strequal(my_netbios_names[n], s))
2859 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2863 /*******************************************************************
2864 set the horrid remote_arch string based on an enum.
2865 ********************************************************************/
2866 void set_remote_arch(enum remote_arch_types type)
2872 fstrcpy(remote_arch, "WfWg");
2875 fstrcpy(remote_arch, "OS2");
2878 fstrcpy(remote_arch, "Win95");
2881 fstrcpy(remote_arch, "WinNT");
2884 fstrcpy(remote_arch, "Win2K");
2887 fstrcpy(remote_arch,"Samba");
2890 ra_type = RA_UNKNOWN;
2891 fstrcpy(remote_arch, "UNKNOWN");
2896 /*******************************************************************
2897 Get the remote_arch type.
2898 ********************************************************************/
2899 enum remote_arch_types get_remote_arch(void)
2905 /*******************************************************************
2906 align a pointer to a multiple of 2 bytes
2907 ********************************************************************/
2908 char *align2(char *q, char *base)
2917 void out_ascii(FILE *f, unsigned char *buf,int len)
2922 fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
2926 void out_data(FILE *f,char *buf1,int len, int per_line)
2928 unsigned char *buf = (unsigned char *)buf1;
2935 fprintf(f, "[%03X] ",i);
2938 fprintf(f, "%02X ",(int)buf[i]);
2940 if (i%(per_line/2) == 0) fprintf(f, " ");
2941 if (i%per_line == 0)
2943 out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
2944 out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
2945 if (i<len) fprintf(f, "[%03X] ",i);
2948 if ((i%per_line) != 0)
2952 n = per_line - (i%per_line);
2954 if (n>(per_line/2)) fprintf(f, " ");
2959 n = MIN(per_line/2,i%per_line);
2960 out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " ");
2961 n = (i%per_line) - n;
2962 if (n>0) out_ascii(f,&buf[i-n],n);
2967 void print_asc(int level, unsigned char *buf,int len)
2971 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2974 void dump_data(int level,char *buf1,int len)
2976 unsigned char *buf = (unsigned char *)buf1;
2980 DEBUG(level,("[%03X] ",i));
2982 DEBUG(level,("%02X ",(int)buf[i]));
2984 if (i%8 == 0) DEBUG(level,(" "));
2986 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
2987 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
2988 if (i<len) DEBUG(level,("[%03X] ",i));
2996 if (n>8) DEBUG(level,(" "));
2997 while (n--) DEBUG(level,(" "));
3000 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
3002 if (n>0) print_asc(level,&buf[i-n],n);
3003 DEBUG(level,("\n"));
3007 char *tab_depth(int depth)
3009 static pstring spaces;
3010 memset(spaces, ' ', depth * 4);
3011 spaces[depth * 4] = 0;
3015 /*****************************************************************************
3016 * Provide a checksum on a string
3018 * Input: s - the null-terminated character string for which the checksum
3019 * will be calculated.
3021 * Output: The checksum value calculated for s.
3023 * ****************************************************************************
3025 int str_checksum(const char *s)
3033 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
3038 } /* str_checksum */
3042 /*****************************************************************
3043 zero a memory area then free it. Used to catch bugs faster
3044 *****************************************************************/
3045 void zero_free(void *p, size_t size)
3052 /*****************************************************************
3053 set our open file limit to a requested max and return the limit
3054 *****************************************************************/
3055 int set_maxfiles(int requested_max)
3057 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
3059 int saved_current_limit;
3061 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
3062 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
3065 return requested_max;
3069 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
3070 * account for the extra fd we need
3071 * as well as the log files and standard
3072 * handles etc. Save the limit we want to set in case
3073 * we are running on an OS that doesn't support this limit (AIX)
3074 * which always returns RLIM_INFINITY for rlp.rlim_max.
3077 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
3079 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
3080 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
3081 (int)rlp.rlim_cur, strerror(errno) ));
3083 return saved_current_limit;
3086 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
3087 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
3090 return saved_current_limit;
3093 #if defined(RLIM_INFINITY)
3094 if(rlp.rlim_cur == RLIM_INFINITY)
3095 return saved_current_limit;
3098 if((int)rlp.rlim_cur > saved_current_limit)
3099 return saved_current_limit;
3101 return rlp.rlim_cur;
3102 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
3104 * No way to know - just guess...
3106 return requested_max;
3111 /*****************************************************************
3112 splits out the last subkey of a key
3113 *****************************************************************/
3114 void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name)
3116 split_at_last_component(full_keyname, key_name, '\\', subkey_name);
3119 /*****************************************************************
3120 splits out the start of the key (HKLM or HKU) and the rest of the key
3121 *****************************************************************/
3122 BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
3126 if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
3133 DEBUG(10, ("reg_split_key: hive %s\n", tmp));
3135 if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
3137 (*reg_type) = HKEY_LOCAL_MACHINE;
3139 else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
3141 (*reg_type) = HKEY_USERS;
3145 DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
3149 if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
3151 fstrcpy(key_name, tmp);
3158 DEBUG(10, ("reg_split_key: name %s\n", key_name));
3164 /*****************************************************************
3165 like mktemp() but make sure that no % characters are used
3166 % characters are bad for us because of the macro subs
3167 *****************************************************************/
3168 char *smbd_mktemp(char *template)
3170 char *p = mktemp(template);
3174 if (!p) return NULL;
3176 while ((p2=strchr(p,'%'))) {
3178 while (sys_stat(p,&st) == 0 && p2[0] < 'Z') {
3179 /* damn, it exists */
3183 /* oh well ... better return something */
3193 /*****************************************************************
3194 like strdup but for memory
3195 *****************************************************************/
3196 void *memdup(void *p, size_t size)
3200 if (!p2) return NULL;
3201 memcpy(p2, p, size);
3205 /*****************************************************************
3206 get local hostname and cache result
3207 *****************************************************************/
3208 char *myhostname(void)