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);
1720 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1726 /****************************************************************************
1727 get my own name and IP
1728 ****************************************************************************/
1729 BOOL get_myname(char *my_name)
1735 /* get my host name */
1736 if (gethostname(hostname, sizeof(hostname)) == -1) {
1737 DEBUG(0,("gethostname failed\n"));
1741 /* Ensure null termination. */
1742 hostname[sizeof(hostname)-1] = '\0';
1745 /* split off any parts after an initial . */
1746 char *p = strchr(hostname,'.');
1749 fstrcpy(my_name,hostname);
1756 /****************************************************************************
1757 true if two IP addresses are equal
1758 ****************************************************************************/
1759 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
1761 return ip1.s_addr == ip2.s_addr;
1765 /****************************************************************************
1766 interpret a protocol description string, with a default
1767 ****************************************************************************/
1768 int interpret_protocol(char *str,int def)
1770 if (strequal(str,"NT1"))
1771 return(PROTOCOL_NT1);
1772 if (strequal(str,"LANMAN2"))
1773 return(PROTOCOL_LANMAN2);
1774 if (strequal(str,"LANMAN1"))
1775 return(PROTOCOL_LANMAN1);
1776 if (strequal(str,"CORE"))
1777 return(PROTOCOL_CORE);
1778 if (strequal(str,"COREPLUS"))
1779 return(PROTOCOL_COREPLUS);
1780 if (strequal(str,"CORE+"))
1781 return(PROTOCOL_COREPLUS);
1783 DEBUG(0,("Unrecognised protocol level %s\n",str));
1788 /****************************************************************************
1789 Return true if a string could be a pure IP address.
1790 ****************************************************************************/
1792 BOOL is_ipaddress(const char *str)
1794 BOOL pure_address = True;
1797 for (i=0; pure_address && str[i]; i++)
1798 if (!(isdigit((int)str[i]) || str[i] == '.'))
1799 pure_address = False;
1801 /* Check that a pure number is not misinterpreted as an IP */
1802 pure_address = pure_address && (strchr(str, '.') != NULL);
1804 return pure_address;
1807 /****************************************************************************
1808 interpret an internet address or name into an IP address in 4 byte form
1809 ****************************************************************************/
1811 uint32 interpret_addr(char *str)
1816 if (strcmp(str,"0.0.0.0") == 0) return(0);
1817 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
1819 /* if it's in the form of an IP address then get the lib to interpret it */
1820 if (is_ipaddress(str)) {
1821 res = inet_addr(str);
1823 /* otherwise assume it's a network name of some sort and use
1825 if ((hp = Get_Hostbyname(str)) == 0) {
1826 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
1829 if(hp->h_addr == NULL) {
1830 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
1833 putip((char *)&res,(char *)hp->h_addr);
1836 if (res == (uint32)-1) return(0);
1841 /*******************************************************************
1842 a convenient addition to interpret_addr()
1843 ******************************************************************/
1844 struct in_addr *interpret_addr2(char *str)
1846 static struct in_addr ret;
1847 uint32 a = interpret_addr(str);
1852 /*******************************************************************
1853 check if an IP is the 0.0.0.0
1854 ******************************************************************/
1855 BOOL zero_ip(struct in_addr ip)
1858 putip((char *)&a,(char *)&ip);
1863 /*******************************************************************
1864 matchname - determine if host name matches IP address
1865 ******************************************************************/
1866 BOOL matchname(char *remotehost,struct in_addr addr)
1871 if ((hp = Get_Hostbyname(remotehost)) == 0) {
1872 DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost));
1877 * Make sure that gethostbyname() returns the "correct" host name.
1878 * Unfortunately, gethostbyname("localhost") sometimes yields
1879 * "localhost.domain". Since the latter host name comes from the
1880 * local DNS, we just have to trust it (all bets are off if the local
1881 * DNS is perverted). We always check the address list, though.
1884 if (strcasecmp(remotehost, hp->h_name)
1885 && strcasecmp(remotehost, "localhost")) {
1886 DEBUG(0,("host name/name mismatch: %s != %s\n",
1887 remotehost, hp->h_name));
1891 /* Look up the host address in the address list we just got. */
1892 for (i = 0; hp->h_addr_list[i]; i++) {
1893 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
1898 * The host name does not map to the original host address. Perhaps
1899 * someone has compromised a name server. More likely someone botched
1900 * it, but that could be dangerous, too.
1903 DEBUG(0,("host name/address mismatch: %s != %s\n",
1904 inet_ntoa(addr), hp->h_name));
1909 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1910 /******************************************************************
1911 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1912 Based on a fix from <Thomas.Hepper@icem.de>.
1913 *******************************************************************/
1915 static void strip_mount_options( pstring *str)
1920 while(*p && !isspace(*p))
1922 while(*p && isspace(*p))
1927 pstrcpy(tmp_str, p);
1928 pstrcpy(*str, tmp_str);
1933 /*******************************************************************
1934 Patch from jkf@soton.ac.uk
1935 Split Luke's automount_server into YP lookup and string splitter
1936 so can easily implement automount_path().
1937 As we may end up doing both, cache the last YP result.
1938 *******************************************************************/
1940 #ifdef WITH_NISPLUS_HOME
1941 static char *automount_lookup(char *user_name)
1943 static fstring last_key = "";
1944 static pstring last_value = "";
1946 char *nis_map = (char *)lp_nis_home_map_name();
1948 char nis_domain[NIS_MAXNAMELEN + 1];
1949 char buffer[NIS_MAXATTRVAL + 1];
1954 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
1955 nis_domain[NIS_MAXNAMELEN] = '\0';
1957 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
1959 if (strcmp(user_name, last_key))
1961 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
1962 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1964 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
1966 if (result->status != NIS_SUCCESS)
1968 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1969 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1973 object = result->objects.objects_val;
1974 if (object->zo_data.zo_type == ENTRY_OBJ)
1976 entry = &object->zo_data.objdata_u.en_data;
1977 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1978 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1980 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1981 pstring_sub(last_value, "&", user_name);
1982 fstrcpy(last_key, user_name);
1986 nis_freeresult(result);
1989 strip_mount_options(&last_value);
1991 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1994 #else /* WITH_NISPLUS_HOME */
1995 static char *automount_lookup(char *user_name)
1997 static fstring last_key = "";
1998 static pstring last_value = "";
2000 int nis_error; /* returned by yp all functions */
2001 char *nis_result; /* yp_match inits this */
2002 int nis_result_len; /* and set this */
2003 char *nis_domain; /* yp_get_default_domain inits this */
2004 char *nis_map = (char *)lp_nis_home_map_name();
2006 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
2008 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
2012 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
2014 if (!strcmp(user_name, last_key))
2016 nis_result = last_value;
2017 nis_result_len = strlen(last_value);
2022 if ((nis_error = yp_match(nis_domain, nis_map,
2023 user_name, strlen(user_name),
2024 &nis_result, &nis_result_len)) != 0)
2026 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
2027 yperr_string(nis_error), user_name, nis_map));
2029 if (!nis_error && nis_result_len >= sizeof(pstring))
2031 nis_result_len = sizeof(pstring)-1;
2033 fstrcpy(last_key, user_name);
2034 strncpy(last_value, nis_result, nis_result_len);
2035 last_value[nis_result_len] = '\0';
2038 strip_mount_options(&last_value);
2040 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
2043 #endif /* WITH_NISPLUS_HOME */
2046 /*******************************************************************
2047 Patch from jkf@soton.ac.uk
2048 This is Luke's original function with the NIS lookup code
2049 moved out to a separate function.
2050 *******************************************************************/
2051 static char *automount_server(char *user_name)
2053 static pstring server_name;
2055 /* use the local machine name as the default */
2056 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2057 pstrcpy(server_name, local_machine);
2059 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2061 if (lp_nis_home_map())
2063 int home_server_len;
2064 char *automount_value = automount_lookup(user_name);
2065 home_server_len = strcspn(automount_value,":");
2066 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
2067 if (home_server_len > sizeof(pstring))
2069 home_server_len = sizeof(pstring);
2071 strncpy(server_name, automount_value, home_server_len);
2072 server_name[home_server_len] = '\0';
2076 DEBUG(4,("Home server: %s\n", server_name));
2081 /*******************************************************************
2082 Patch from jkf@soton.ac.uk
2083 Added this to implement %p (NIS auto-map version of %H)
2084 *******************************************************************/
2085 static char *automount_path(char *user_name)
2087 static pstring server_path;
2089 /* use the passwd entry as the default */
2090 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2091 /* pstrcpy() copes with get_user_home_dir() returning NULL */
2092 pstrcpy(server_path, get_user_home_dir(user_name));
2094 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2096 if (lp_nis_home_map())
2098 char *home_path_start;
2099 char *automount_value = automount_lookup(user_name);
2100 home_path_start = strchr(automount_value,':');
2101 if (home_path_start != NULL)
2103 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
2104 home_path_start?(home_path_start+1):""));
2105 pstrcpy(server_path, home_path_start+1);
2110 DEBUG(4,("Home server path: %s\n", server_path));
2115 /*******************************************************************
2116 Given a pointer to a %$(NAME) expand it as an environment variable.
2117 Return the number of characters by which the pointer should be advanced.
2118 Based on code by Branko Cibej <branko.cibej@hermes.si>
2119 When this is called p points at the '%' character.
2120 ********************************************************************/
2122 static size_t expand_env_var(char *p, int len)
2136 * Look for the terminating ')'.
2139 if ((q = strchr(p,')')) == NULL) {
2140 DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
2145 * Extract the name from within the %$(NAME) string.
2149 copylen = MIN((q-r),(sizeof(envname)-1));
2150 strncpy(envname,r,copylen);
2151 envname[copylen] = '\0';
2153 if ((envval = getenv(envname)) == NULL) {
2154 DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
2159 * Copy the full %$(NAME) into envname so it
2163 copylen = MIN((q+1-p),(sizeof(envname)-1));
2164 strncpy(envname,p,copylen);
2165 envname[copylen] = '\0';
2166 string_sub(p,envname,envval,len);
2167 return 0; /* Allow the environment contents to be parsed. */
2170 /*******************************************************************
2171 Substitute strings with useful parameters.
2172 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
2173 Paul Rippin <pr3245@nopc.eurostat.cec.be>.
2174 ********************************************************************/
2176 void standard_sub_basic(char *str)
2180 struct passwd *pass;
2181 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
2183 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
2185 int l = sizeof(pstring) - (int)(p-str);
2188 DEBUG(0,("ERROR: string overflow by %d in standard_sub_basic(%.50s)\n",
2198 if ((pass = Get_Pwnam(username,False))!=NULL) {
2199 string_sub(p,"%G",gidtoname(pass->pw_gid),l);
2205 case 'N' : string_sub(p,"%N", automount_server(username),l); break;
2206 case 'I' : string_sub(p,"%I", client_addr(Client),l); break;
2207 case 'L' : string_sub(p,"%L", local_machine,l); break;
2208 case 'M' : string_sub(p,"%M", client_name(Client),l); break;
2209 case 'R' : string_sub(p,"%R", remote_proto,l); break;
2210 case 'T' : string_sub(p,"%T", timestring(False),l); break;
2211 case 'U' : string_sub(p,"%U", username,l); break;
2212 case 'a' : string_sub(p,"%a", remote_arch,l); break;
2215 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
2216 string_sub(p,"%d", pidstr,l);
2219 case 'h' : string_sub(p,"%h", myhostname(),l); break;
2220 case 'm' : string_sub(p,"%m", remote_machine,l); break;
2221 case 'v' : string_sub(p,"%v", VERSION,l); break;
2222 case '$' : p += expand_env_var(p,l); break; /* Expand environment variables */
2223 case '\0': p++; break; /* don't run off end if last character is % */
2224 default : p+=2; break;
2231 /****************************************************************************
2232 Do some standard substitutions in a string.
2233 ****************************************************************************/
2235 void standard_sub(connection_struct *conn,char *str)
2239 for (s=str; (p=strchr(s, '%'));s=p) {
2240 int l = sizeof(pstring) - (int)(p-str);
2244 if ((home = get_user_home_dir(conn->user))) {
2245 string_sub(p,"%H",home,l);
2252 string_sub(p,"%P",conn->connectpath,l);
2257 lp_servicename(SNUM(conn)),l);
2262 gidtoname(conn->gid),l);
2265 string_sub(p,"%u",conn->user,l);
2268 /* Patch from jkf@soton.ac.uk Left the %N (NIS
2269 * server name) in standard_sub_basic as it is
2270 * a feature for logon servers, hence uses the
2271 * username. The %p (NIS server path) code is
2272 * here as it is used instead of the default
2273 * "path =" string in [homes] and so needs the
2274 * service name, not the username. */
2277 automount_path(lp_servicename(SNUM(conn))),l);
2281 break; /* don't run off the end of the string
2289 standard_sub_basic(str);
2294 /*******************************************************************
2295 are two IPs on the same subnet?
2296 ********************************************************************/
2297 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
2299 uint32 net1,net2,nmask;
2301 nmask = ntohl(mask.s_addr);
2302 net1 = ntohl(ip1.s_addr);
2303 net2 = ntohl(ip2.s_addr);
2305 return((net1 & nmask) == (net2 & nmask));
2309 /****************************************************************************
2310 a wrapper for gethostbyname() that tries with all lower and all upper case
2311 if the initial name fails
2312 ****************************************************************************/
2313 struct hostent *Get_Hostbyname(const char *name)
2315 char *name2 = strdup(name);
2316 struct hostent *ret;
2320 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
2326 * This next test is redundent and causes some systems (with
2327 * broken isalnum() calls) problems.
2332 if (!isalnum(*name2))
2339 ret = sys_gethostbyname(name2);
2346 /* try with all lowercase */
2348 ret = sys_gethostbyname(name2);
2355 /* try with all uppercase */
2357 ret = sys_gethostbyname(name2);
2364 /* nothing works :-( */
2370 /****************************************************************************
2371 check if a process exists. Does this work on all unixes?
2372 ****************************************************************************/
2374 BOOL process_exists(pid_t pid)
2376 return(kill(pid,0) == 0 || errno != ESRCH);
2380 /*******************************************************************
2381 turn a uid into a user name
2382 ********************************************************************/
2383 char *uidtoname(uid_t uid)
2385 static char name[40];
2386 struct passwd *pass = sys_getpwuid(uid);
2387 if (pass) return(pass->pw_name);
2388 slprintf(name, sizeof(name) - 1, "%d",(int)uid);
2393 /*******************************************************************
2394 turn a gid into a group name
2395 ********************************************************************/
2397 char *gidtoname(gid_t gid)
2399 static char name[40];
2400 struct group *grp = getgrgid(gid);
2401 if (grp) return(grp->gr_name);
2402 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
2406 /*******************************************************************
2407 turn a user name into a uid
2408 ********************************************************************/
2409 uid_t nametouid(const char *name)
2411 struct passwd *pass;
2415 u = strtol(name, &p, 0);
2416 if (p != name) return u;
2418 pass = sys_getpwnam(name);
2419 if (pass) return(pass->pw_uid);
2423 /*******************************************************************
2424 turn a group name into a gid
2425 ********************************************************************/
2426 gid_t nametogid(const char *name)
2432 g = strtol(name, &p, 0);
2433 if (p != name) return g;
2435 grp = getgrnam(name);
2436 if (grp) return(grp->gr_gid);
2440 /*******************************************************************
2441 something really nasty happened - panic!
2442 ********************************************************************/
2443 void smb_panic(char *why)
2445 char *cmd = lp_panic_action();
2449 DEBUG(0,("PANIC: %s\n", why));
2455 /*******************************************************************
2456 a readdir wrapper which just returns the file name
2457 ********************************************************************/
2458 char *readdirname(DIR *p)
2460 SMB_STRUCT_DIRENT *ptr;
2463 if (!p) return(NULL);
2465 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
2466 if (!ptr) return(NULL);
2468 dname = ptr->d_name;
2471 if (telldir(p) < 0) return(NULL);
2474 #ifdef HAVE_BROKEN_READDIR
2475 /* using /usr/ucb/cc is BAD */
2481 memcpy(buf, dname, NAMLEN(ptr)+1);
2488 /*******************************************************************
2489 Utility function used to decide if the last component
2490 of a path matches a (possibly wildcarded) entry in a namelist.
2491 ********************************************************************/
2493 BOOL is_in_path(char *name, name_compare_entry *namelist)
2495 pstring last_component;
2498 DEBUG(8, ("is_in_path: %s\n", name));
2500 /* if we have no list it's obviously not in the path */
2501 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
2503 DEBUG(8,("is_in_path: no name list.\n"));
2507 /* Get the last component of the unix name. */
2508 p = strrchr(name, '/');
2509 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
2510 last_component[sizeof(last_component)-1] = '\0';
2512 for(; namelist->name != NULL; namelist++)
2514 if(namelist->is_wild)
2517 * Look for a wildcard match. Use the old
2518 * 'unix style' mask match, rather than the
2521 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
2523 DEBUG(8,("is_in_path: mask match succeeded\n"));
2529 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
2530 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
2532 DEBUG(8,("is_in_path: match succeeded\n"));
2537 DEBUG(8,("is_in_path: match not found\n"));
2542 /*******************************************************************
2543 Strip a '/' separated list into an array of
2544 name_compare_enties structures suitable for
2545 passing to is_in_path(). We do this for
2546 speed so we can pre-parse all the names in the list
2547 and don't do it for each call to is_in_path().
2548 namelist is modified here and is assumed to be
2549 a copy owned by the caller.
2550 We also check if the entry contains a wildcard to
2551 remove a potentially expensive call to mask_match
2553 ********************************************************************/
2555 void set_namearray(name_compare_entry **ppname_array, char *namelist)
2558 char *nameptr = namelist;
2559 int num_entries = 0;
2562 (*ppname_array) = NULL;
2564 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
2567 /* We need to make two passes over the string. The
2568 first to count the number of elements, the second
2573 if ( *nameptr == '/' )
2575 /* cope with multiple (useless) /s) */
2579 /* find the next / */
2580 name_end = strchr(nameptr, '/');
2582 /* oops - the last check for a / didn't find one. */
2583 if (name_end == NULL)
2586 /* next segment please */
2587 nameptr = name_end + 1;
2591 if(num_entries == 0)
2594 if(( (*ppname_array) = (name_compare_entry *)malloc(
2595 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
2597 DEBUG(0,("set_namearray: malloc fail\n"));
2601 /* Now copy out the names */
2606 if ( *nameptr == '/' )
2608 /* cope with multiple (useless) /s) */
2612 /* find the next / */
2613 if ((name_end = strchr(nameptr, '/')) != NULL)
2618 /* oops - the last check for a / didn't find one. */
2619 if(name_end == NULL)
2622 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
2623 (strchr( nameptr, '*')!=NULL));
2624 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
2626 DEBUG(0,("set_namearray: malloc fail (1)\n"));
2630 /* next segment please */
2631 nameptr = name_end + 1;
2635 (*ppname_array)[i].name = NULL;
2640 /****************************************************************************
2641 routine to free a namearray.
2642 ****************************************************************************/
2644 void free_namearray(name_compare_entry *name_array)
2649 if(name_array->name != NULL)
2650 free(name_array->name);
2652 free((char *)name_array);
2655 /****************************************************************************
2656 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
2657 ****************************************************************************/
2659 uint32 map_lock_offset(uint32 high, uint32 low)
2663 uint32 highcopy = high;
2666 * Try and find out how many significant bits there are in high.
2669 for(i = 0; highcopy; i++)
2673 * We use 31 bits not 32 here as POSIX
2674 * lock offsets may not be negative.
2677 mask = (~0) << (31 - i);
2680 return 0; /* Fail. */
2687 /****************************************************************************
2688 routine to do file locking
2689 ****************************************************************************/
2691 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2694 SMB_STRUCT_FLOCK lock;
2696 #if defined(LARGE_SMB_OFF_T)
2698 * In the 64 bit locking case we store the original
2699 * values in case we have to map to a 32 bit lock on
2700 * a filesystem that doesn't support 64 bit locks.
2702 SMB_OFF_T orig_offset = offset;
2703 SMB_OFF_T orig_count = count;
2704 #endif /* LARGE_SMB_OFF_T */
2706 if(lp_ole_locking_compat()) {
2707 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
2708 SMB_OFF_T mask = (mask2<<2);
2710 /* make sure the count is reasonable, we might kill the lockd otherwise */
2713 /* the offset is often strange - remove 2 of its bits if either of
2714 the top two bits are set. Shift the top ones by two bits. This
2715 still allows OLE2 apps to operate, but should stop lockd from
2717 if ((offset & mask) != 0)
2718 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
2720 SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
2721 SMB_OFF_T mask = (mask2<<1);
2722 SMB_OFF_T neg_mask = ~mask;
2724 /* interpret negative counts as large numbers */
2728 /* no negative offsets */
2732 /* count + offset must be in range */
2733 while ((offset < 0 || (offset + count < 0)) && mask)
2736 mask = ((mask >> 1) & neg_mask);
2740 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
2743 lock.l_whence = SEEK_SET;
2744 lock.l_start = offset;
2750 ret = fcntl(fd,op,&lock);
2755 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
2756 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
2757 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
2759 /* 32 bit NFS file system, retry with smaller offset */
2761 lock.l_len = count & 0x7fffffff;
2762 ret = fcntl(fd,op,&lock);
2766 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
2769 if (op == SMB_F_GETLK)
2772 (lock.l_type != F_UNLCK) &&
2773 (lock.l_pid != 0) &&
2774 (lock.l_pid != getpid()))
2776 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
2780 /* it must be not locked or locked by me */
2784 /* a lock set or unset */
2787 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2788 (double)offset,(double)count,op,type,strerror(errno)));
2790 /* perhaps it doesn't support this sort of locking?? */
2791 if (errno == EINVAL)
2794 #if defined(LARGE_SMB_OFF_T)
2797 * Ok - if we get here then we have a 64 bit lock request
2798 * that has returned EINVAL. Try and map to 31 bits for offset
2799 * and length and try again. This may happen if a filesystem
2800 * doesn't support 64 bit offsets (efs/ufs) although the underlying
2803 uint32 off_low = (orig_offset & 0xFFFFFFFF);
2804 uint32 off_high = ((orig_offset >> 32) & 0xFFFFFFFF);
2806 lock.l_len = (orig_count & 0x7FFFFFFF);
2807 lock.l_start = (SMB_OFF_T)map_lock_offset(off_high, off_low);
2808 ret = fcntl(fd,op,&lock);
2811 if (errno == EINVAL)
2813 DEBUG(3,("locking not supported? returning True\n"));
2818 DEBUG(3,("64 -> 32 bit modified lock call successful\n"));
2821 #else /* LARGE_SMB_OFF_T */
2822 DEBUG(3,("locking not supported? returning True\n"));
2824 #endif /* LARGE_SMB_OFF_T */
2830 /* everything went OK */
2831 DEBUG(8,("Lock call successful\n"));
2839 /*******************************************************************
2840 is the name specified one of my netbios names
2841 returns true is it is equal, false otherwise
2842 ********************************************************************/
2843 BOOL is_myname(char *s)
2848 for (n=0; my_netbios_names[n]; n++) {
2849 if (strequal(my_netbios_names[n], s))
2852 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2856 /*******************************************************************
2857 set the horrid remote_arch string based on an enum.
2858 ********************************************************************/
2859 void set_remote_arch(enum remote_arch_types type)
2865 fstrcpy(remote_arch, "WfWg");
2868 fstrcpy(remote_arch, "OS2");
2871 fstrcpy(remote_arch, "Win95");
2874 fstrcpy(remote_arch, "WinNT");
2877 fstrcpy(remote_arch, "Win2K");
2880 fstrcpy(remote_arch,"Samba");
2883 ra_type = RA_UNKNOWN;
2884 fstrcpy(remote_arch, "UNKNOWN");
2889 /*******************************************************************
2890 Get the remote_arch type.
2891 ********************************************************************/
2892 enum remote_arch_types get_remote_arch(void)
2898 /*******************************************************************
2899 align a pointer to a multiple of 2 bytes
2900 ********************************************************************/
2901 char *align2(char *q, char *base)
2910 void out_ascii(FILE *f, unsigned char *buf,int len)
2915 fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
2919 void out_data(FILE *f,char *buf1,int len, int per_line)
2921 unsigned char *buf = (unsigned char *)buf1;
2928 fprintf(f, "[%03X] ",i);
2931 fprintf(f, "%02X ",(int)buf[i]);
2933 if (i%(per_line/2) == 0) fprintf(f, " ");
2934 if (i%per_line == 0)
2936 out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
2937 out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
2938 if (i<len) fprintf(f, "[%03X] ",i);
2941 if ((i%per_line) != 0)
2945 n = per_line - (i%per_line);
2947 if (n>(per_line/2)) fprintf(f, " ");
2952 n = MIN(per_line/2,i%per_line);
2953 out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " ");
2954 n = (i%per_line) - n;
2955 if (n>0) out_ascii(f,&buf[i-n],n);
2960 void print_asc(int level, unsigned char *buf,int len)
2964 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2967 void dump_data(int level,char *buf1,int len)
2969 unsigned char *buf = (unsigned char *)buf1;
2973 DEBUG(level,("[%03X] ",i));
2975 DEBUG(level,("%02X ",(int)buf[i]));
2977 if (i%8 == 0) DEBUG(level,(" "));
2979 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
2980 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
2981 if (i<len) DEBUG(level,("[%03X] ",i));
2989 if (n>8) DEBUG(level,(" "));
2990 while (n--) DEBUG(level,(" "));
2993 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
2995 if (n>0) print_asc(level,&buf[i-n],n);
2996 DEBUG(level,("\n"));
3000 char *tab_depth(int depth)
3002 static pstring spaces;
3003 memset(spaces, ' ', depth * 4);
3004 spaces[depth * 4] = 0;
3008 /*****************************************************************************
3009 * Provide a checksum on a string
3011 * Input: s - the null-terminated character string for which the checksum
3012 * will be calculated.
3014 * Output: The checksum value calculated for s.
3016 * ****************************************************************************
3018 int str_checksum(const char *s)
3026 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
3031 } /* str_checksum */
3035 /*****************************************************************
3036 zero a memory area then free it. Used to catch bugs faster
3037 *****************************************************************/
3038 void zero_free(void *p, size_t size)
3045 /*****************************************************************
3046 set our open file limit to a requested max and return the limit
3047 *****************************************************************/
3048 int set_maxfiles(int requested_max)
3050 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
3052 int saved_current_limit;
3054 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
3055 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
3058 return requested_max;
3062 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
3063 * account for the extra fd we need
3064 * as well as the log files and standard
3065 * handles etc. Save the limit we want to set in case
3066 * we are running on an OS that doesn't support this limit (AIX)
3067 * which always returns RLIM_INFINITY for rlp.rlim_max.
3070 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
3072 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
3073 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
3074 (int)rlp.rlim_cur, strerror(errno) ));
3076 return saved_current_limit;
3079 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
3080 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
3083 return saved_current_limit;
3086 #if defined(RLIM_INFINITY)
3087 if(rlp.rlim_cur == RLIM_INFINITY)
3088 return saved_current_limit;
3091 if((int)rlp.rlim_cur > saved_current_limit)
3092 return saved_current_limit;
3094 return rlp.rlim_cur;
3095 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
3097 * No way to know - just guess...
3099 return requested_max;
3104 /*****************************************************************
3105 splits out the last subkey of a key
3106 *****************************************************************/
3107 void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name)
3109 split_at_last_component(full_keyname, key_name, '\\', subkey_name);
3112 /*****************************************************************
3113 splits out the start of the key (HKLM or HKU) and the rest of the key
3114 *****************************************************************/
3115 BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
3119 if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
3126 DEBUG(10, ("reg_split_key: hive %s\n", tmp));
3128 if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
3130 (*reg_type) = HKEY_LOCAL_MACHINE;
3132 else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
3134 (*reg_type) = HKEY_USERS;
3138 DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
3142 if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
3144 fstrcpy(key_name, tmp);
3151 DEBUG(10, ("reg_split_key: name %s\n", key_name));
3157 /*****************************************************************
3158 like mktemp() but make sure that no % characters are used
3159 % characters are bad for us because of the macro subs
3160 *****************************************************************/
3161 char *smbd_mktemp(char *template)
3163 char *p = mktemp(template);
3167 if (!p) return NULL;
3169 while ((p2=strchr(p,'%'))) {
3171 while (sys_stat(p,&st) == 0 && p2[0] < 'Z') {
3172 /* damn, it exists */
3176 /* oh well ... better return something */
3186 /*****************************************************************
3187 like strdup but for memory
3188 *****************************************************************/
3189 void *memdup(void *p, size_t size)
3193 if (!p2) return NULL;
3194 memcpy(p2, p, size);
3198 /*****************************************************************
3199 get local hostname and cache result
3200 *****************************************************************/
3201 char *myhostname(void)
3211 /*****************************************************************
3212 a useful function for returning a path in the Samba lock directory
3213 *****************************************************************/
3214 char *lock_path(char *name)
3216 static pstring fname;
3218 pstrcpy(fname,lp_lockdir());
3219 trim_string(fname,"","/");
3221 if (!directory_exist(fname,NULL)) {
3226 pstrcat(fname,name);