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 */
61 extern int DEBUGLEVEL
;
63 int Protocol
= PROTOCOL_COREPLUS
;
65 /* a default finfo structure to ensure all fields are sensible */
66 file_info def_finfo
= {-1,0,0,0,0,0,0,""};
68 /* the client file descriptor */
71 /* this is used by the chaining code */
77 case handling on filenames
79 int case_default
= CASE_LOWER
;
81 /* the following control case operations - they are put here so the
82 client can link easily */
85 BOOL use_mangled_map
= False
;
86 BOOL short_case_preserve
;
89 fstring remote_machine
="";
90 fstring local_machine
="";
91 fstring remote_arch
="UNKNOWN";
92 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
93 fstring remote_proto
="UNKNOWN";
94 pstring myhostname
="";
95 pstring user_socket_options
="";
97 pstring sesssetup_user
="";
98 pstring samlogon_user
="";
100 BOOL sam_logon_in_ssb
= False
;
102 pstring global_myname
= "";
103 fstring global_myworkgroup
= "";
104 char **my_netbios_names
;
106 static char *filename_dos(char *path
,char *buf
);
110 /****************************************************************************
111 find a suitable temporary directory. The result should be copied immediately
112 as it may be overwritten by a subsequent call
113 ****************************************************************************/
117 if ((p
= getenv("MC_TMPDIR")) || (p
= getenv("TMPDIR"))) {
123 /****************************************************************************
124 determine whether we are in the specified group
125 ****************************************************************************/
127 BOOL
in_group(gid_t group
, gid_t current_gid
, int ngroups
, gid_t
*groups
)
131 if (group
== current_gid
) return(True
);
133 for (i
=0;i
<ngroups
;i
++)
134 if (group
== groups
[i
])
141 /****************************************************************************
142 like atoi but gets the value up to the separater character
143 ****************************************************************************/
144 char *Atoic(char *p
, int *n
, char *c
)
146 if (!isdigit((int)*p
))
148 DEBUG(5, ("Atoic: malformed number\n"));
154 while ((*p
) && isdigit((int)*p
))
159 if (strchr(c
, *p
) == NULL
)
161 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c
));
168 /*************************************************************************
169 reads a list of numbers
170 *************************************************************************/
171 char *get_numlist(char *p
, uint32
**num
, int *count
)
175 if (num
== NULL
|| count
== NULL
)
183 while ((p
= Atoic(p
, &val
, ":,")) != NULL
&& (*p
) != ':')
185 (*num
) = Realloc((*num
), ((*count
)+1) * sizeof(uint32
));
190 (*num
)[(*count
)] = val
;
198 /*******************************************************************
199 copy an IP address from one buffer to another
200 ********************************************************************/
201 void putip(void *dest
,void *src
)
207 #define TRUNCATE_NETBIOS_NAME 1
209 /*******************************************************************
210 convert, possibly using a stupid microsoft-ism which has destroyed
211 the transport independence of netbios (for CIFS vendors that usually
212 use the Win95-type methods, not for NT to NT communication, which uses
213 DCE/RPC and therefore full-length unicode strings...) a dns name into
216 the netbios name (NOT necessarily null-terminated) is truncated to 15
219 ******************************************************************/
220 char *dns_to_netbios_name(char *dns_name
)
222 static char netbios_name
[16];
224 StrnCpy(netbios_name
, dns_name
, 15);
225 netbios_name
[15] = 0;
227 #ifdef TRUNCATE_NETBIOS_NAME
228 /* ok. this is because of a stupid microsoft-ism. if the called host
229 name contains a '.', microsoft clients expect you to truncate the
230 netbios name up to and including the '.' this even applies, by
231 mistake, to workgroup (domain) names, which is _really_ daft.
233 for (i
= 15; i
>= 0; i
--)
235 if (netbios_name
[i
] == '.')
241 #endif /* TRUNCATE_NETBIOS_NAME */
247 /****************************************************************************
248 interpret the weird netbios "name". Return the name type
249 ****************************************************************************/
250 static int name_interpret(char *in
,char *out
)
253 int len
= (*in
++) / 2;
257 if (len
> 30 || len
<1) return(0);
261 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
265 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
273 /* Handle any scope names */
276 *out
++ = '.'; /* Scope names are separated by periods */
277 len
= *(unsigned char *)in
++;
278 StrnCpy(out
, in
, len
);
287 /****************************************************************************
288 mangle a name into netbios format
290 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
291 ****************************************************************************/
292 int name_mangle( char *In
, char *Out
, char name_type
)
299 extern pstring global_scope
;
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
!= global_scope
; i
++, len
++ )
325 switch( global_scope
[i
] )
331 return( name_len(Out
) );
338 p
[len
+1] = global_scope
[i
];
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
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 string_sub(s
, "\\\\", "\\");
582 while ((p
= strstr(s
,"\\..\\")) != NULL
)
589 if ((p
=strrchr(s
,'\\')) != NULL
)
596 trim_string(s
,NULL
,"\\..");
598 string_sub(s
, "\\.\\", "\\");
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 string_sub(s
, "//","/");
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 string_sub(s
,"//","/");
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,("Cannot 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,("Cannot 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)
1047 memcpy(p
,buf
+ofs
,2);
1050 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
1057 /****************************************************************************
1058 extract a netbios name from a buf
1059 ****************************************************************************/
1060 int name_extract(char *buf
,int ofs
,char *name
)
1062 char *p
= name_ptr(buf
,ofs
);
1063 int d
= PTR_DIFF(p
,buf
+ofs
);
1065 if (d
< -50 || d
> 50) return(0);
1066 return(name_interpret(p
,name
));
1069 /****************************************************************************
1070 return the total storage length of a mangled name
1071 ****************************************************************************/
1072 int name_len(char *s1
)
1074 /* NOTE: this argument _must_ be unsigned */
1075 unsigned char *s
= (unsigned char *)s1
;
1078 /* If the two high bits of the byte are set, return 2. */
1079 if (0xC0 == (*s
& 0xC0))
1082 /* Add up the length bytes. */
1083 for (len
= 1; (*s
); s
+= (*s
) + 1) {
1085 SMB_ASSERT(len
< 80);
1092 /*******************************************************************
1093 sleep for a specified number of milliseconds
1094 ********************************************************************/
1098 struct timeval tval
,t1
,t2
;
1105 tval
.tv_sec
= (t
-tdiff
)/1000;
1106 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
1110 sys_select(0,&fds
,&tval
);
1113 tdiff
= TvalDiff(&t1
,&t2
);
1118 /*********************************************************
1119 * Recursive routine that is called by unix_mask_match.
1120 * Does the actual matching. This is the 'original code'
1121 * used by the unix matcher.
1122 *********************************************************/
1123 static BOOL
unix_do_match(char *str
, char *regexp
, int case_sig
)
1127 for( p
= regexp
; *p
&& *str
; ) {
1134 /* Look for a character matching
1135 the one after the '*' */
1138 return True
; /* Automatic match */
1140 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
1142 if(unix_do_match(str
,p
,case_sig
))
1156 if(toupper(*str
) != toupper(*p
))
1166 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1169 if (!*str
&& *p
== '?')
1171 while (*p
== '?') p
++;
1175 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
1181 /*********************************************************
1182 * Routine to match a given string with a regexp - uses
1183 * simplified regexp that takes * and ? only. Case can be
1184 * significant or not.
1185 * This is the 'original code' used by the unix matcher.
1186 *********************************************************/
1188 static BOOL
unix_mask_match(char *str
, char *regexp
, int case_sig
,BOOL trans2
)
1192 fstring ebase
,eext
,sbase
,sext
;
1196 /* Make local copies of str and regexp */
1197 StrnCpy(p1
,regexp
,sizeof(pstring
)-1);
1198 StrnCpy(p2
,str
,sizeof(pstring
)-1);
1200 if (!strchr(p2
,'.')) {
1204 /* Remove any *? and ** as they are meaningless */
1205 for(p
= p1
; *p
; p
++)
1206 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*'))
1207 (void)pstrcpy( &p
[1], &p
[2]);
1209 if (strequal(p1
,"*")) return(True
);
1211 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
1217 if ((p
=strrchr(p1
,'.'))) {
1226 if (!strequal(p2
,".") && !strequal(p2
,"..") && (p
=strrchr(p2
,'.'))) {
1236 matched
= unix_do_match(sbase
,ebase
,case_sig
) &&
1237 (trans2
|| unix_do_match(sext
,eext
,case_sig
));
1239 DEBUG(8,("unix_mask_match returning %d\n", matched
));
1244 /*********************************************************
1245 * Recursive routine that is called by mask_match.
1246 * Does the actual matching. Returns True if matched,
1247 * False if failed. This is the 'new' NT style matcher.
1248 *********************************************************/
1250 BOOL
do_match(char *str
, char *regexp
, int case_sig
)
1254 for( p
= regexp
; *p
&& *str
; ) {
1261 /* Look for a character matching
1262 the one after the '*' */
1265 return True
; /* Automatic match */
1267 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
1269 /* Now eat all characters that match, as
1270 we want the *last* character to match. */
1271 while(*str
&& (case_sig
? (*p
== *str
) : (toupper(*p
)==toupper(*str
))))
1273 str
--; /* We've eaten the match char after the '*' */
1274 if(do_match(str
,p
,case_sig
)) {
1291 if(toupper(*str
) != toupper(*p
)) {
1303 if (!*p
&& str
[0] == '.' && str
[1] == 0) {
1307 if (!*str
&& *p
== '?') {
1313 if(!*str
&& (*p
== '*' && p
[1] == '\0')) {
1321 /*********************************************************
1322 * Routine to match a given string with a regexp - uses
1323 * simplified regexp that takes * and ? only. Case can be
1324 * significant or not.
1325 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
1326 * This is the new 'NT style' matcher.
1327 *********************************************************/
1329 BOOL
mask_match(char *str
, char *regexp
, int case_sig
,BOOL trans2
)
1332 pstring t_pattern
, t_filename
, te_pattern
, te_filename
;
1333 fstring ebase
,eext
,sbase
,sext
;
1335 BOOL matched
= False
;
1337 /* Make local copies of str and regexp */
1338 pstrcpy(t_pattern
,regexp
);
1339 pstrcpy(t_filename
,str
);
1343 /* a special case for 16 bit apps */
1344 if (strequal(t_pattern
,"????????.???"))
1345 pstrcpy(t_pattern
,"*");
1349 * Handle broken clients that send us old 8.3 format.
1351 string_sub(t_pattern
,"????????","*");
1352 string_sub(t_pattern
,".???",".*");
1358 * Not sure if this is a good idea. JRA.
1360 if(trans2
&& is_8_3(t_pattern
,False
) && is_8_3(t_filename
,False
))
1365 if (!strchr(t_filename
,'.')) {
1366 pstrcat(t_filename
,".");
1370 /* Remove any *? and ** as they are meaningless */
1371 string_sub(t_pattern
, "*?", "*");
1372 string_sub(t_pattern
, "**", "*");
1374 if (strequal(t_pattern
,"*"))
1377 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename
, t_pattern
, case_sig
));
1381 * Match each component of the regexp, split up by '.'
1384 char *fp
, *rp
, *cp2
, *cp1
;
1385 BOOL last_wcard_was_star
= False
;
1386 int num_path_components
, num_regexp_components
;
1388 pstrcpy(te_pattern
,t_pattern
);
1389 pstrcpy(te_filename
,t_filename
);
1391 * Remove multiple "*." patterns.
1393 string_sub(te_pattern
, "*.*.", "*.");
1394 num_regexp_components
= count_chars(te_pattern
, '.');
1395 num_path_components
= count_chars(te_filename
, '.');
1398 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
1400 if(num_regexp_components
== 0)
1401 matched
= do_match( te_filename
, te_pattern
, case_sig
);
1403 for( cp1
= te_pattern
, cp2
= te_filename
; cp1
;) {
1404 fp
= strchr(cp2
, '.');
1407 rp
= strchr(cp1
, '.');
1411 if(cp1
[strlen(cp1
)-1] == '*')
1412 last_wcard_was_star
= True
;
1414 last_wcard_was_star
= False
;
1416 if(!do_match(cp2
, cp1
, case_sig
))
1419 cp1
= rp
? rp
+ 1 : NULL
;
1420 cp2
= fp
? fp
+ 1 : "";
1422 if(last_wcard_was_star
|| ((cp1
!= NULL
) && (*cp1
== '*'))) {
1423 /* Eat the extra path components. */
1426 for(i
= 0; i
< num_path_components
- num_regexp_components
; i
++) {
1427 fp
= strchr(cp2
, '.');
1431 if((cp1
!= NULL
) && do_match( cp2
, cp1
, case_sig
)) {
1432 cp2
= fp
? fp
+ 1 : "";
1435 cp2
= fp
? fp
+ 1 : "";
1437 num_path_components
-= i
;
1440 if(cp1
== NULL
&& ((*cp2
== '\0') || last_wcard_was_star
))
1445 /* -------------------------------------------------
1446 * Behaviour of Win95
1447 * for 8.3 filenames and 8.3 Wildcards
1448 * -------------------------------------------------
1450 if (strequal (t_filename
, ".")) {
1452 * Patterns: *.* *. ?. ? ????????.??? are valid.
1455 if(strequal(t_pattern
, "*.*") || strequal(t_pattern
, "*.") ||
1456 strequal(t_pattern
, "????????.???") ||
1457 strequal(t_pattern
, "?.") || strequal(t_pattern
, "?"))
1459 } else if (strequal (t_filename
, "..")) {
1461 * Patterns: *.* *. ?. ? *.? ????????.??? are valid.
1464 if(strequal(t_pattern
, "*.*") || strequal(t_pattern
, "*.") ||
1465 strequal(t_pattern
, "?.") || strequal(t_pattern
, "?") ||
1466 strequal(t_pattern
, "????????.???") ||
1467 strequal(t_pattern
, "*.?") || strequal(t_pattern
, "?.*"))
1471 if ((p
= strrchr (t_pattern
, '.'))) {
1473 * Wildcard has a suffix.
1476 fstrcpy (ebase
, t_pattern
);
1478 fstrcpy (eext
, p
+ 1);
1480 /* pattern ends in DOT: treat as if there is no DOT */
1482 if (strequal (ebase
, "*"))
1487 * No suffix for wildcard.
1489 fstrcpy (ebase
, t_pattern
);
1493 p
= strrchr (t_filename
, '.');
1494 if (p
&& (p
[1] == 0) ) {
1496 * Filename has an extension of '.' only.
1498 *p
= 0; /* nuke dot at end of string */
1499 p
= 0; /* and treat it as if there is no extension */
1504 * Filename has an extension.
1507 fstrcpy (sbase
, t_filename
);
1508 fstrcpy (sext
, p
+ 1);
1510 matched
= do_match(sbase
, ebase
, case_sig
)
1511 && do_match(sext
, eext
, case_sig
);
1513 /* pattern has no extension */
1514 /* Really: match complete filename with pattern ??? means exactly 3 chars */
1515 matched
= do_match(str
, ebase
, case_sig
);
1519 * Filename has no extension.
1521 fstrcpy (sbase
, t_filename
);
1524 /* pattern has extension */
1525 matched
= do_match(sbase
, ebase
, case_sig
)
1526 && do_match(sext
, eext
, case_sig
);
1528 matched
= do_match(sbase
, ebase
, case_sig
);
1529 #ifdef EMULATE_WEIRD_W95_MATCHING
1531 * Even Microsoft has some problems
1532 * Behaviour Win95 -> local disk
1533 * is different from Win95 -> smb drive from Nt 4.0
1534 * This branch would reflect the Win95 local disk behaviour
1537 /* a? matches aa and a in w95 */
1538 fstrcat (sbase
, ".");
1539 matched
= do_match(sbase
, ebase
, case_sig
);
1547 DEBUG(8,("mask_match returning %d\n", matched
));
1554 /****************************************************************************
1555 set the length of a file from a filedescriptor.
1556 Returns 0 on success, -1 on failure.
1557 ****************************************************************************/
1559 int set_filelen(int fd
, SMB_OFF_T len
)
1561 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1562 extend a file with ftruncate. Provide alternate implementation
1565 #ifdef HAVE_FTRUNCATE_EXTEND
1566 return sys_ftruncate(fd
, len
);
1570 SMB_OFF_T currpos
= sys_lseek(fd
, (SMB_OFF_T
)0, SEEK_CUR
);
1574 /* Do an fstat to see if the file is longer than
1575 the requested size (call ftruncate),
1576 or shorter, in which case seek to len - 1 and write 1
1578 if(sys_fstat(fd
, &st
)<0)
1582 if (S_ISFIFO(st
.st_mode
))
1586 if(st
.st_size
== len
)
1588 if(st
.st_size
> len
)
1589 return sys_ftruncate(fd
, len
);
1591 if(sys_lseek(fd
, len
-1, SEEK_SET
) != len
-1)
1593 if(write(fd
, &c
, 1)!=1)
1595 /* Seek to where we were */
1596 if(sys_lseek(fd
, currpos
, SEEK_SET
) != currpos
)
1604 /****************************************************************************
1605 this is a version of setbuffer() for those machines that only have setvbuf
1606 ****************************************************************************/
1607 void setbuffer(FILE *f
,char *buf
,int bufsize
)
1609 setvbuf(f
,buf
,_IOFBF
,bufsize
);
1614 /****************************************************************************
1615 parse out a filename from a path name. Assumes dos style filenames.
1616 ****************************************************************************/
1617 static char *filename_dos(char *path
,char *buf
)
1619 char *p
= strrchr(path
,'\\');
1631 /****************************************************************************
1632 expand a pointer to be a particular size
1633 ****************************************************************************/
1634 void *Realloc(void *p
,size_t size
)
1640 DEBUG(5,("Realloc asked for 0 bytes\n"));
1645 ret
= (void *)malloc(size
);
1647 ret
= (void *)realloc(p
,size
);
1652 smb_mem_write_info(ret
, dbf
);
1657 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size
));
1663 /****************************************************************************
1664 get my own name and IP
1665 ****************************************************************************/
1666 BOOL
get_myname(char *my_name
,struct in_addr
*ip
)
1673 /* get my host name */
1674 if (gethostname(hostname
, sizeof(hostname
)) == -1)
1676 DEBUG(0,("gethostname failed\n"));
1680 /* Ensure null termination. */
1681 hostname
[sizeof(hostname
)-1] = '\0';
1684 if ((hp
= Get_Hostbyname(hostname
)) == 0)
1686 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname
));
1692 /* split off any parts after an initial . */
1693 char *p
= strchr(hostname
,'.');
1696 fstrcpy(my_name
,hostname
);
1700 putip((char *)ip
,(char *)hp
->h_addr
);
1706 /****************************************************************************
1707 true if two IP addresses are equal
1708 ****************************************************************************/
1709 BOOL
ip_equal(struct in_addr ip1
,struct in_addr ip2
)
1712 a1
= ntohl(ip1
.s_addr
);
1713 a2
= ntohl(ip2
.s_addr
);
1718 /****************************************************************************
1719 interpret a protocol description string, with a default
1720 ****************************************************************************/
1721 int interpret_protocol(char *str
,int def
)
1723 if (strequal(str
,"NT1"))
1724 return(PROTOCOL_NT1
);
1725 if (strequal(str
,"LANMAN2"))
1726 return(PROTOCOL_LANMAN2
);
1727 if (strequal(str
,"LANMAN1"))
1728 return(PROTOCOL_LANMAN1
);
1729 if (strequal(str
,"CORE"))
1730 return(PROTOCOL_CORE
);
1731 if (strequal(str
,"COREPLUS"))
1732 return(PROTOCOL_COREPLUS
);
1733 if (strequal(str
,"CORE+"))
1734 return(PROTOCOL_COREPLUS
);
1736 DEBUG(0,("Unrecognised protocol level %s\n",str
));
1742 /****************************************************************************
1743 interpret an internet address or name into an IP address in 4 byte form
1744 ****************************************************************************/
1745 uint32
interpret_addr(char *str
)
1750 BOOL pure_address
= True
;
1752 if (strcmp(str
,"0.0.0.0") == 0) return(0);
1753 if (strcmp(str
,"255.255.255.255") == 0) return(0xFFFFFFFF);
1755 for (i
=0; pure_address
&& str
[i
]; i
++)
1756 if (!(isdigit((int)str
[i
]) || str
[i
] == '.'))
1757 pure_address
= False
;
1759 /* if it's in the form of an IP address then get the lib to interpret it */
1761 res
= inet_addr(str
);
1763 /* otherwise assume it's a network name of some sort and use
1765 if ((hp
= Get_Hostbyname(str
)) == 0) {
1766 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str
));
1769 if(hp
->h_addr
== NULL
) {
1770 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str
));
1773 putip((char *)&res
,(char *)hp
->h_addr
);
1776 if (res
== (uint32
)-1) return(0);
1781 /*******************************************************************
1782 a convenient addition to interpret_addr()
1783 ******************************************************************/
1784 struct in_addr
*interpret_addr2(char *str
)
1786 static struct in_addr ret
;
1787 uint32 a
= interpret_addr(str
);
1792 /*******************************************************************
1793 check if an IP is the 0.0.0.0
1794 ******************************************************************/
1795 BOOL
zero_ip(struct in_addr ip
)
1798 putip((char *)&a
,(char *)&ip
);
1803 /*******************************************************************
1804 matchname - determine if host name matches IP address
1805 ******************************************************************/
1806 BOOL
matchname(char *remotehost
,struct in_addr addr
)
1811 if ((hp
= Get_Hostbyname(remotehost
)) == 0) {
1812 DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost
));
1817 * Make sure that gethostbyname() returns the "correct" host name.
1818 * Unfortunately, gethostbyname("localhost") sometimes yields
1819 * "localhost.domain". Since the latter host name comes from the
1820 * local DNS, we just have to trust it (all bets are off if the local
1821 * DNS is perverted). We always check the address list, though.
1824 if (strcasecmp(remotehost
, hp
->h_name
)
1825 && strcasecmp(remotehost
, "localhost")) {
1826 DEBUG(0,("host name/name mismatch: %s != %s\n",
1827 remotehost
, hp
->h_name
));
1831 /* Look up the host address in the address list we just got. */
1832 for (i
= 0; hp
->h_addr_list
[i
]; i
++) {
1833 if (memcmp(hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof(addr
)) == 0)
1838 * The host name does not map to the original host address. Perhaps
1839 * someone has compromised a name server. More likely someone botched
1840 * it, but that could be dangerous, too.
1843 DEBUG(0,("host name/address mismatch: %s != %s\n",
1844 inet_ntoa(addr
), hp
->h_name
));
1849 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1850 /******************************************************************
1851 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1852 Based on a fix from <Thomas.Hepper@icem.de>.
1853 *******************************************************************/
1855 static void strip_mount_options( pstring
*str
)
1860 while(*p
&& !isspace(*p
))
1862 while(*p
&& isspace(*p
))
1867 pstrcpy(tmp_str
, p
);
1868 pstrcpy(*str
, tmp_str
);
1873 /*******************************************************************
1874 Patch from jkf@soton.ac.uk
1875 Split Luke's automount_server into YP lookup and string splitter
1876 so can easily implement automount_path().
1877 As we may end up doing both, cache the last YP result.
1878 *******************************************************************/
1880 #ifdef WITH_NISPLUS_HOME
1881 static char *automount_lookup(char *user_name
)
1883 static fstring last_key
= "";
1884 static pstring last_value
= "";
1886 char *nis_map
= (char *)lp_nis_home_map_name();
1888 char buffer
[NIS_MAXATTRVAL
+ 1];
1893 DEBUG(5, ("NIS+ Domain: %s\n", (char *)nis_local_directory()));
1895 if (strcmp(user_name
, last_key
))
1897 slprintf(buffer
, sizeof(buffer
)-1, "[%s=%s]%s.%s", "key", user_name
, nis_map
,
1898 (char *)nis_local_directory());
1899 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
1901 if (result
= nis_list(buffer
, RETURN_RESULT
, NULL
, NULL
))
1903 if (result
->status
!= NIS_SUCCESS
)
1905 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
1906 fstrcpy(last_key
, ""); pstrcpy(last_value
, "");
1910 object
= result
->objects
.objects_val
;
1911 if (object
->zo_data
.zo_type
== ENTRY_OBJ
)
1913 entry
= &object
->zo_data
.objdata_u
.en_data
;
1914 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
1915 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
1917 pstrcpy(last_value
, entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
1918 string_sub(last_value
, "&", user_name
);
1919 fstrcpy(last_key
, user_name
);
1923 nis_freeresult(result
);
1926 strip_mount_options(&last_value
);
1928 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name
, last_value
));
1931 #else /* WITH_NISPLUS_HOME */
1932 static char *automount_lookup(char *user_name
)
1934 static fstring last_key
= "";
1935 static pstring last_value
= "";
1937 int nis_error
; /* returned by yp all functions */
1938 char *nis_result
; /* yp_match inits this */
1939 int nis_result_len
; /* and set this */
1940 char *nis_domain
; /* yp_get_default_domain inits this */
1941 char *nis_map
= (char *)lp_nis_home_map_name();
1943 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0)
1945 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
1949 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
1951 if (!strcmp(user_name
, last_key
))
1953 nis_result
= last_value
;
1954 nis_result_len
= strlen(last_value
);
1959 if ((nis_error
= yp_match(nis_domain
, nis_map
,
1960 user_name
, strlen(user_name
),
1961 &nis_result
, &nis_result_len
)) != 0)
1963 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1964 yperr_string(nis_error
), user_name
, nis_map
));
1966 if (!nis_error
&& nis_result_len
>= sizeof(pstring
))
1968 nis_result_len
= sizeof(pstring
)-1;
1970 fstrcpy(last_key
, user_name
);
1971 strncpy(last_value
, nis_result
, nis_result_len
);
1972 last_value
[nis_result_len
] = '\0';
1975 strip_mount_options(&last_value
);
1977 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, last_value
));
1980 #endif /* WITH_NISPLUS_HOME */
1983 /*******************************************************************
1984 Patch from jkf@soton.ac.uk
1985 This is Luke's original function with the NIS lookup code
1986 moved out to a separate function.
1987 *******************************************************************/
1988 static char *automount_server(char *user_name
)
1990 static pstring server_name
;
1992 /* use the local machine name as the default */
1993 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
1994 pstrcpy(server_name
, local_machine
);
1996 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
1998 if (lp_nis_home_map())
2000 int home_server_len
;
2001 char *automount_value
= automount_lookup(user_name
);
2002 home_server_len
= strcspn(automount_value
,":");
2003 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len
));
2004 if (home_server_len
> sizeof(pstring
))
2006 home_server_len
= sizeof(pstring
);
2008 strncpy(server_name
, automount_value
, home_server_len
);
2009 server_name
[home_server_len
] = '\0';
2013 DEBUG(4,("Home server: %s\n", server_name
));
2018 /*******************************************************************
2019 Patch from jkf@soton.ac.uk
2020 Added this to implement %p (NIS auto-map version of %H)
2021 *******************************************************************/
2022 static char *automount_path(char *user_name
)
2024 static pstring server_path
;
2026 /* use the passwd entry as the default */
2027 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2028 /* pstrcpy() copes with get_home_dir() returning NULL */
2029 pstrcpy(server_path
, get_home_dir(user_name
));
2031 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2033 if (lp_nis_home_map())
2035 char *home_path_start
;
2036 char *automount_value
= automount_lookup(user_name
);
2037 home_path_start
= strchr(automount_value
,':');
2038 if (home_path_start
!= NULL
)
2040 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
2041 home_path_start
?(home_path_start
+1):""));
2042 pstrcpy(server_path
, home_path_start
+1);
2047 DEBUG(4,("Home server path: %s\n", server_path
));
2053 /*******************************************************************
2054 sub strings with useful parameters
2055 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
2056 Paul Rippin <pr3245@nopc.eurostat.cec.be>
2057 ********************************************************************/
2058 void standard_sub_basic(char *str
)
2062 struct passwd
*pass
;
2063 char *username
= sam_logon_in_ssb
? samlogon_user
: sesssetup_user
;
2065 for (s
= str
; s
&& *s
&& (p
= strchr(s
,'%')); s
= p
)
2071 if ((pass
= Get_Pwnam(username
,False
))!=NULL
)
2073 string_sub(p
,"%G",gidtoname(pass
->pw_gid
));
2081 case 'N' : string_sub(p
,"%N", automount_server(username
)); break;
2082 case 'I' : string_sub(p
,"%I", client_addr(Client
)); break;
2083 case 'L' : string_sub(p
,"%L", local_machine
); break;
2084 case 'M' : string_sub(p
,"%M", client_name(Client
)); break;
2085 case 'R' : string_sub(p
,"%R", remote_proto
); break;
2086 case 'T' : string_sub(p
,"%T", timestring()); break;
2087 case 'U' : string_sub(p
,"%U", username
); break;
2088 case 'a' : string_sub(p
,"%a", remote_arch
); break;
2091 slprintf(pidstr
,sizeof(pidstr
) - 1, "%d",(int)getpid());
2092 string_sub(p
,"%d", pidstr
);
2095 case 'h' : string_sub(p
,"%h", myhostname
); break;
2096 case 'm' : string_sub(p
,"%m", remote_machine
); break;
2097 case 'v' : string_sub(p
,"%v", VERSION
); break;
2098 case '$' : /* Expand environment variables */
2100 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
2111 if ((q
= strchr(p
,')')) == NULL
)
2113 DEBUG(0,("standard_sub_basic: Unterminated environment \
2114 variable [%s]\n", p
));
2120 copylen
= MIN((q
-r
),(sizeof(envname
)-1));
2121 strncpy(envname
,r
,copylen
);
2122 envname
[copylen
] = '\0';
2124 if ((envval
= getenv(envname
)) == NULL
)
2126 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
2132 copylen
= MIN((q
+1-p
),(sizeof(envname
)-1));
2133 strncpy(envname
,p
,copylen
);
2134 envname
[copylen
] = '\0';
2135 string_sub(p
,envname
,envval
);
2138 case '\0': p
++; break; /* don't run off end if last character is % */
2139 default : p
+=2; break;
2146 /****************************************************************************
2147 do some standard substitutions in a string
2148 ****************************************************************************/
2149 void standard_sub(connection_struct
*conn
,char *str
)
2153 for (s
=str
; (p
=strchr(s
, '%'));s
=p
) {
2156 if ((home
= get_home_dir(conn
->user
))) {
2157 string_sub(p
,"%H",home
);
2164 string_sub(p
,"%P",conn
->connectpath
);
2169 lp_servicename(SNUM(conn
)));
2174 gidtoname(conn
->gid
));
2177 string_sub(p
,"%u",conn
->user
);
2180 /* Patch from jkf@soton.ac.uk Left the %N (NIS
2181 * server name) in standard_sub_basic as it is
2182 * a feature for logon servers, hence uses the
2183 * username. The %p (NIS server path) code is
2184 * here as it is used instead of the default
2185 * "path =" string in [homes] and so needs the
2186 * service name, not the username. */
2189 automount_path(lp_servicename(SNUM(conn
))));
2193 break; /* don't run off the end of the string
2201 standard_sub_basic(str
);
2206 /*******************************************************************
2207 are two IPs on the same subnet?
2208 ********************************************************************/
2209 BOOL
same_net(struct in_addr ip1
,struct in_addr ip2
,struct in_addr mask
)
2211 uint32 net1
,net2
,nmask
;
2213 nmask
= ntohl(mask
.s_addr
);
2214 net1
= ntohl(ip1
.s_addr
);
2215 net2
= ntohl(ip2
.s_addr
);
2217 return((net1
& nmask
) == (net2
& nmask
));
2221 /****************************************************************************
2222 a wrapper for gethostbyname() that tries with all lower and all upper case
2223 if the initial name fails
2224 ****************************************************************************/
2225 struct hostent
*Get_Hostbyname(const char *name
)
2227 char *name2
= strdup(name
);
2228 struct hostent
*ret
;
2232 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
2238 * This next test is redundent and causes some systems (with
2239 * broken isalnum() calls) problems.
2244 if (!isalnum(*name2
))
2251 ret
= sys_gethostbyname(name2
);
2258 /* try with all lowercase */
2260 ret
= sys_gethostbyname(name2
);
2267 /* try with all uppercase */
2269 ret
= sys_gethostbyname(name2
);
2276 /* nothing works :-( */
2282 /*******************************************************************
2283 turn a uid into a user name
2284 ********************************************************************/
2285 char *uidtoname(uid_t uid
)
2287 static char name
[40];
2288 struct passwd
*pass
= getpwuid(uid
);
2289 if (pass
) return(pass
->pw_name
);
2290 slprintf(name
, sizeof(name
) - 1, "%d",(int)uid
);
2295 /*******************************************************************
2296 turn a gid into a group name
2297 ********************************************************************/
2299 char *gidtoname(gid_t gid
)
2301 static char name
[40];
2302 struct group
*grp
= getgrgid(gid
);
2303 if (grp
) return(grp
->gr_name
);
2304 slprintf(name
,sizeof(name
) - 1, "%d",(int)gid
);
2308 /*******************************************************************
2309 turn a user name into a uid
2310 ********************************************************************/
2311 uid_t
nametouid(const char *name
)
2313 struct passwd
*pass
= getpwnam(name
);
2314 if (pass
) return(pass
->pw_uid
);
2318 /*******************************************************************
2319 something really nasty happened - panic!
2320 ********************************************************************/
2321 void smb_panic(char *why
)
2323 char *cmd
= lp_panic_action();
2327 DEBUG(0,("PANIC: %s\n", why
));
2333 /*******************************************************************
2334 a readdir wrapper which just returns the file name
2335 ********************************************************************/
2336 char *readdirname(DIR *p
)
2338 SMB_STRUCT_DIRENT
*ptr
;
2341 if (!p
) return(NULL
);
2343 ptr
= (SMB_STRUCT_DIRENT
*)sys_readdir(p
);
2344 if (!ptr
) return(NULL
);
2346 dname
= ptr
->d_name
;
2349 if (telldir(p
) < 0) return(NULL
);
2352 #ifdef HAVE_BROKEN_READDIR
2353 /* using /usr/ucb/cc is BAD */
2359 memcpy(buf
, dname
, NAMLEN(ptr
)+1);
2366 /*******************************************************************
2367 Utility function used to decide if the last component
2368 of a path matches a (possibly wildcarded) entry in a namelist.
2369 ********************************************************************/
2371 BOOL
is_in_path(char *name
, name_compare_entry
*namelist
)
2373 pstring last_component
;
2376 DEBUG(8, ("is_in_path: %s\n", name
));
2378 /* if we have no list it's obviously not in the path */
2379 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
)))
2381 DEBUG(8,("is_in_path: no name list.\n"));
2385 /* Get the last component of the unix name. */
2386 p
= strrchr(name
, '/');
2387 strncpy(last_component
, p
? ++p
: name
, sizeof(last_component
)-1);
2388 last_component
[sizeof(last_component
)-1] = '\0';
2390 for(; namelist
->name
!= NULL
; namelist
++)
2392 if(namelist
->is_wild
)
2395 * Look for a wildcard match. Use the old
2396 * 'unix style' mask match, rather than the
2399 if (unix_mask_match(last_component
, namelist
->name
, case_sensitive
, False
))
2401 DEBUG(8,("is_in_path: mask match succeeded\n"));
2407 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
2408 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0)))
2410 DEBUG(8,("is_in_path: match succeeded\n"));
2415 DEBUG(8,("is_in_path: match not found\n"));
2420 /*******************************************************************
2421 Strip a '/' separated list into an array of
2422 name_compare_enties structures suitable for
2423 passing to is_in_path(). We do this for
2424 speed so we can pre-parse all the names in the list
2425 and don't do it for each call to is_in_path().
2426 namelist is modified here and is assumed to be
2427 a copy owned by the caller.
2428 We also check if the entry contains a wildcard to
2429 remove a potentially expensive call to mask_match
2431 ********************************************************************/
2433 void set_namearray(name_compare_entry
**ppname_array
, char *namelist
)
2436 char *nameptr
= namelist
;
2437 int num_entries
= 0;
2440 (*ppname_array
) = NULL
;
2442 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
2445 /* We need to make two passes over the string. The
2446 first to count the number of elements, the second
2451 if ( *nameptr
== '/' )
2453 /* cope with multiple (useless) /s) */
2457 /* find the next / */
2458 name_end
= strchr(nameptr
, '/');
2460 /* oops - the last check for a / didn't find one. */
2461 if (name_end
== NULL
)
2464 /* next segment please */
2465 nameptr
= name_end
+ 1;
2469 if(num_entries
== 0)
2472 if(( (*ppname_array
) = (name_compare_entry
*)malloc(
2473 (num_entries
+ 1) * sizeof(name_compare_entry
))) == NULL
)
2475 DEBUG(0,("set_namearray: malloc fail\n"));
2479 /* Now copy out the names */
2484 if ( *nameptr
== '/' )
2486 /* cope with multiple (useless) /s) */
2490 /* find the next / */
2491 if ((name_end
= strchr(nameptr
, '/')) != NULL
)
2496 /* oops - the last check for a / didn't find one. */
2497 if(name_end
== NULL
)
2500 (*ppname_array
)[i
].is_wild
= ((strchr( nameptr
, '?')!=NULL
) ||
2501 (strchr( nameptr
, '*')!=NULL
));
2502 if(((*ppname_array
)[i
].name
= strdup(nameptr
)) == NULL
)
2504 DEBUG(0,("set_namearray: malloc fail (1)\n"));
2508 /* next segment please */
2509 nameptr
= name_end
+ 1;
2513 (*ppname_array
)[i
].name
= NULL
;
2518 /****************************************************************************
2519 routine to free a namearray.
2520 ****************************************************************************/
2522 void free_namearray(name_compare_entry
*name_array
)
2527 if(name_array
->name
!= NULL
)
2528 free(name_array
->name
);
2530 free((char *)name_array
);
2533 /****************************************************************************
2534 routine to do file locking
2535 ****************************************************************************/
2536 BOOL
fcntl_lock(int fd
, int op
, SMB_OFF_T offset
, SMB_OFF_T count
, int type
)
2538 #ifdef HAVE_FCNTL_LOCK
2539 SMB_STRUCT_FLOCK lock
;
2542 if(lp_ole_locking_compat()) {
2543 SMB_OFF_T mask2
= ((SMB_OFF_T
)0x3) << (SMB_OFF_T_BITS
-4);
2544 SMB_OFF_T mask
= (mask2
<<2);
2546 /* make sure the count is reasonable, we might kill the lockd otherwise */
2549 /* the offset is often strange - remove 2 of its bits if either of
2550 the top two bits are set. Shift the top ones by two bits. This
2551 still allows OLE2 apps to operate, but should stop lockd from
2553 if ((offset
& mask
) != 0)
2554 offset
= (offset
& ~mask
) | (((offset
& mask
) >> 2) & mask2
);
2556 SMB_OFF_T mask2
= ((SMB_OFF_T
)0x4) << (SMB_OFF_T_BITS
-4);
2557 SMB_OFF_T mask
= (mask2
<<1);
2558 SMB_OFF_T neg_mask
= ~mask
;
2560 /* interpret negative counts as large numbers */
2564 /* no negative offsets */
2568 /* count + offset must be in range */
2569 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
2572 mask
= ((mask
>> 1) & neg_mask
);
2576 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd
,op
,(double)offset
,(double)count
,type
));
2579 lock
.l_whence
= SEEK_SET
;
2580 lock
.l_start
= offset
;
2586 ret
= fcntl(fd
,op
,&lock
);
2591 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset
,(double)count
);
2592 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
2593 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
2595 /* 32 bit NFS file system, retry with smaller offset */
2597 lock
.l_len
= count
& 0xffffffff;
2598 ret
= fcntl(fd
,op
,&lock
);
2602 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno
,strerror(errno
)));
2605 if (op
== SMB_F_GETLK
)
2608 (lock
.l_type
!= F_UNLCK
) &&
2609 (lock
.l_pid
!= 0) &&
2610 (lock
.l_pid
!= getpid()))
2612 DEBUG(3,("fd %d is locked by pid %d\n",fd
,(int)lock
.l_pid
));
2616 /* it must be not locked or locked by me */
2620 /* a lock set or unset */
2623 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2624 (double)offset
,(double)count
,op
,type
,strerror(errno
)));
2626 /* perhaps it doesn't support this sort of locking?? */
2627 if (errno
== EINVAL
)
2629 DEBUG(3,("locking not supported? returning True\n"));
2636 /* everything went OK */
2637 DEBUG(8,("Lock call successful\n"));
2645 /*******************************************************************
2646 is the name specified one of my netbios names
2647 returns true is it is equal, false otherwise
2648 ********************************************************************/
2649 BOOL
is_myname(char *s
)
2654 for (n
=0; my_netbios_names
[n
]; n
++) {
2655 if (strequal(my_netbios_names
[n
], s
))
2658 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
2662 /*******************************************************************
2663 set the horrid remote_arch string based on an enum.
2664 ********************************************************************/
2665 void set_remote_arch(enum remote_arch_types type
)
2671 fstrcpy(remote_arch
, "WfWg");
2674 fstrcpy(remote_arch
, "OS2");
2677 fstrcpy(remote_arch
, "Win95");
2680 fstrcpy(remote_arch
, "WinNT");
2683 fstrcpy(remote_arch
,"Samba");
2686 ra_type
= RA_UNKNOWN
;
2687 fstrcpy(remote_arch
, "UNKNOWN");
2692 /*******************************************************************
2693 Get the remote_arch type.
2694 ********************************************************************/
2695 enum remote_arch_types
get_remote_arch(void)
2701 /*******************************************************************
2702 align a pointer to a multiple of 2 bytes
2703 ********************************************************************/
2704 char *align2(char *q
, char *base
)
2713 void out_ascii(FILE *f
, unsigned char *buf
,int len
)
2718 fprintf(f
, "%c", isprint(buf
[i
])?buf
[i
]:'.');
2722 void out_data(FILE *f
,char *buf1
,int len
, int per_line
)
2724 unsigned char *buf
= (unsigned char *)buf1
;
2731 fprintf(f
, "[%03X] ",i
);
2734 fprintf(f
, "%02X ",(int)buf
[i
]);
2736 if (i
%(per_line
/2) == 0) fprintf(f
, " ");
2737 if (i
%per_line
== 0)
2739 out_ascii(f
,&buf
[i
-per_line
],per_line
/2); fprintf(f
, " ");
2740 out_ascii(f
,&buf
[i
-per_line
/2],per_line
/2); fprintf(f
, "\n");
2741 if (i
<len
) fprintf(f
, "[%03X] ",i
);
2744 if ((i
%per_line
) != 0)
2748 n
= per_line
- (i
%per_line
);
2750 if (n
>(per_line
/2)) fprintf(f
, " ");
2755 n
= MIN(per_line
/2,i
%per_line
);
2756 out_ascii(f
,&buf
[i
-(i
%per_line
)],n
); fprintf(f
, " ");
2757 n
= (i
%per_line
) - n
;
2758 if (n
>0) out_ascii(f
,&buf
[i
-n
],n
);
2763 void print_asc(int level
, unsigned char *buf
,int len
)
2767 DEBUG(level
,("%c", isprint(buf
[i
])?buf
[i
]:'.'));
2770 void dump_data(int level
,char *buf1
,int len
)
2772 unsigned char *buf
= (unsigned char *)buf1
;
2776 DEBUG(level
,("[%03X] ",i
));
2778 DEBUG(level
,("%02X ",(int)buf
[i
]));
2780 if (i
%8 == 0) DEBUG(level
,(" "));
2782 print_asc(level
,&buf
[i
-16],8); DEBUG(level
,(" "));
2783 print_asc(level
,&buf
[i
-8],8); DEBUG(level
,("\n"));
2784 if (i
<len
) DEBUG(level
,("[%03X] ",i
));
2792 if (n
>8) DEBUG(level
,(" "));
2793 while (n
--) DEBUG(level
,(" "));
2796 print_asc(level
,&buf
[i
-(i
%16)],n
); DEBUG(level
,(" "));
2798 if (n
>0) print_asc(level
,&buf
[i
-n
],n
);
2799 DEBUG(level
,("\n"));
2803 char *tab_depth(int depth
)
2805 static pstring spaces
;
2806 memset(spaces
, ' ', depth
* 4);
2807 spaces
[depth
* 4] = 0;
2811 /*****************************************************************************
2812 * Provide a checksum on a string
2814 * Input: s - the null-terminated character string for which the checksum
2815 * will be calculated.
2817 * Output: The checksum value calculated for s.
2819 * ****************************************************************************
2821 int str_checksum(const char *s
)
2829 res
^= (c
<< (i
% 15)) ^ (c
>> (15-(i
%15)));
2834 } /* str_checksum */
2838 /*****************************************************************
2839 zero a memory area then free it. Used to catch bugs faster
2840 *****************************************************************/
2841 void zero_free(void *p
, size_t size
)
2848 /*****************************************************************
2849 set our open file limit to a requested max and return the limit
2850 *****************************************************************/
2851 int set_maxfiles(int requested_max
)
2853 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2855 int saved_current_limit
;
2857 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2858 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2861 return requested_max
;
2865 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2866 * account for the extra fd we need
2867 * as well as the log files and standard
2868 * handles etc. Save the limit we want to set in case
2869 * we are running on an OS that doesn't support this limit (AIX)
2870 * which always returns RLIM_INFINITY for rlp.rlim_max.
2873 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
2875 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
2876 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2877 (int)rlp
.rlim_cur
, strerror(errno
) ));
2879 return saved_current_limit
;
2882 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2883 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2886 return saved_current_limit
;
2889 #if defined(RLIM_INFINITY)
2890 if(rlp
.rlim_cur
== RLIM_INFINITY
)
2891 return saved_current_limit
;
2894 if((int)rlp
.rlim_cur
> saved_current_limit
)
2895 return saved_current_limit
;
2897 return rlp
.rlim_cur
;
2898 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2900 * No way to know - just guess...
2902 return requested_max
;
2907 /*****************************************************************
2908 splits out the last subkey of a key
2909 *****************************************************************/
2910 void reg_get_subkey(char *full_keyname
, char *key_name
, char *subkey_name
)
2912 split_at_last_component(full_keyname
, key_name
, '\\', subkey_name
);
2915 /*****************************************************************
2916 splits out the start of the key (HKLM or HKU) and the rest of the key
2917 *****************************************************************/
2918 BOOL
reg_split_key(char *full_keyname
, uint32
*reg_type
, char *key_name
)
2922 if (!next_token(&full_keyname
, tmp
, "\\", sizeof(tmp
)))
2929 DEBUG(10, ("reg_split_key: hive %s\n", tmp
));
2931 if (strequal(tmp
, "HKLM") || strequal(tmp
, "HKEY_LOCAL_MACHINE"))
2933 (*reg_type
) = HKEY_LOCAL_MACHINE
;
2935 else if (strequal(tmp
, "HKU") || strequal(tmp
, "HKEY_USERS"))
2937 (*reg_type
) = HKEY_USERS
;
2941 DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp
));
2945 if (next_token(NULL
, tmp
, "\n\r", sizeof(tmp
)))
2947 fstrcpy(key_name
, tmp
);
2954 DEBUG(10, ("reg_split_key: name %s\n", key_name
));