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 #include <rpcsvc/nis.h>
28 #include "rpcsvc/ypclnt.h"
34 #undef Realloc /* SSLeay defines this and samba has a function of this name */
41 extern int DEBUGLEVEL;
43 int Protocol = PROTOCOL_COREPLUS;
45 /* a default finfo structure to ensure all fields are sensible */
46 file_info def_finfo = {-1,0,0,0,0,0,0,""};
48 /* the client file descriptor */
51 /* this is used by the chaining code */
57 case handling on filenames
59 int case_default = CASE_LOWER;
61 /* the following control case operations - they are put here so the
62 client can link easily */
65 BOOL use_mangled_map = False;
66 BOOL short_case_preserve;
69 fstring remote_machine="";
70 fstring local_machine="";
71 fstring remote_arch="UNKNOWN";
72 static enum remote_arch_types ra_type = RA_UNKNOWN;
73 fstring remote_proto="UNKNOWN";
74 pstring myhostname="";
75 pstring user_socket_options="";
77 pstring sesssetup_user="";
78 pstring samlogon_user="";
80 BOOL sam_logon_in_ssb = False;
82 pstring global_myname = "";
83 fstring global_myworkgroup = "";
84 char **my_netbios_names;
86 static char *filename_dos(char *path,char *buf);
89 /*************************************************************
90 initialise password databases, domain names, domain sid.
91 **************************************************************/
92 BOOL init_myworkgroup(void)
94 fstrcpy(global_myworkgroup, lp_workgroup());
96 if (strequal(global_myworkgroup,"*"))
98 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
104 /****************************************************************************
105 find a suitable temporary directory. The result should be copied immediately
106 as it may be overwritten by a subsequent call
107 ****************************************************************************/
111 if ((p = getenv("TMPDIR"))) {
117 /****************************************************************************
118 determine whether we are in the specified group
119 ****************************************************************************/
121 BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
125 if (group == current_gid) return(True);
127 for (i=0;i<ngroups;i++)
128 if (group == groups[i])
135 /****************************************************************************
136 gets either a hex number (0xNNN) or decimal integer (NNN).
137 ****************************************************************************/
138 uint32 get_number(const char *tmp)
140 if (strnequal(tmp, "0x", 2))
142 return strtoul(tmp, (char**)NULL, 16);
146 return strtoul(tmp, (char**)NULL, 10);
150 /****************************************************************************
151 like atoi but gets the value up to the separater character
152 ****************************************************************************/
153 char *Atoic(char *p, int *n, char *c)
157 DEBUG(5, ("Atoic: malformed number\n"));
161 (*n) = (int)get_number(p);
163 if (strnequal(p, "0x", 2))
168 while ((*p) && isdigit(*p))
173 if (strchr(c, *p) == NULL)
175 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
182 uint32 *add_num_to_list(uint32 **num, int *count, int val)
184 (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
189 (*num)[(*count)] = val;
195 /*************************************************************************
196 reads a list of numbers
197 *************************************************************************/
198 char *get_numlist(char *p, uint32 **num, int *count)
202 if (num == NULL || count == NULL)
210 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':')
212 if (add_num_to_list(num, count, val) == NULL)
222 /*******************************************************************
223 copy an IP address from one buffer to another
224 ********************************************************************/
225 void putip(void *dest,void *src)
231 #define TRUNCATE_NETBIOS_NAME 1
233 /*******************************************************************
234 convert, possibly using a stupid microsoft-ism which has destroyed
235 the transport independence of netbios (for CIFS vendors that usually
236 use the Win95-type methods, not for NT to NT communication, which uses
237 DCE/RPC and therefore full-length unicode strings...) a dns name into
240 the netbios name (NOT necessarily null-terminated) is truncated to 15
243 ******************************************************************/
244 char *dns_to_netbios_name(char *dns_name)
246 static char netbios_name[16];
248 StrnCpy(netbios_name, dns_name, 15);
249 netbios_name[15] = 0;
251 #ifdef TRUNCATE_NETBIOS_NAME
252 /* ok. this is because of a stupid microsoft-ism. if the called host
253 name contains a '.', microsoft clients expect you to truncate the
254 netbios name up to and including the '.' this even applies, by
255 mistake, to workgroup (domain) names, which is _really_ daft.
257 for (i = 15; i >= 0; i--)
259 if (netbios_name[i] == '.')
265 #endif /* TRUNCATE_NETBIOS_NAME */
271 /****************************************************************************
272 interpret the weird netbios "name". Return the name type
273 ****************************************************************************/
274 static int name_interpret(char *in,char *out)
277 int len = (*in++) / 2;
281 if (len > 30 || len<1) return(0);
285 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
289 *out = ((in[0]-'A')<<4) + (in[1]-'A');
297 /* Handle any scope names */
300 *out++ = '.'; /* Scope names are separated by periods */
301 len = *(unsigned char *)in++;
302 StrnCpy(out, in, len);
311 /****************************************************************************
312 mangle a name into netbios format
314 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
315 ****************************************************************************/
316 int name_mangle( char *In, char *Out, char name_type )
324 /* Safely copy the input string, In, into buf[]. */
325 (void)memset( buf, 0, 20 );
326 if (strcmp(In,"*") == 0)
329 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
331 /* Place the length of the first field into the output buffer. */
335 /* Now convert the name to the rfc1001/1002 format. */
336 for( i = 0; i < 16; i++ )
338 c = toupper( buf[i] );
339 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
340 p[(i*2)+1] = (c & 0x000F) + 'A';
345 /* Add the scope string. */
346 for( i = 0, len = 0; NULL != scope; i++, len++ )
354 return( name_len(Out) );
366 return( name_len(Out) );
369 /*******************************************************************
370 check if a file exists
371 ********************************************************************/
372 BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
375 if (!sbuf) sbuf = &st;
377 if (sys_stat(fname,sbuf) != 0)
380 return(S_ISREG(sbuf->st_mode));
383 /*******************************************************************
385 ********************************************************************/
386 int file_rename(char *from, char *to)
388 int rcode = rename (from, to);
392 /* Rename across filesystems needed. */
393 rcode = copy_reg (from, to);
398 /*******************************************************************
399 check a files mod time
400 ********************************************************************/
401 time_t file_modtime(char *fname)
405 if (sys_stat(fname,&st) != 0)
411 /*******************************************************************
412 check if a directory exists
413 ********************************************************************/
414 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
421 if (sys_stat(dname,st) != 0)
424 ret = S_ISDIR(st->st_mode);
430 /*******************************************************************
431 returns the size in bytes of the named file
432 ********************************************************************/
433 SMB_OFF_T file_size(char *file_name)
437 if(sys_stat(file_name,&buf) != 0)
438 return (SMB_OFF_T)-1;
442 /*******************************************************************
443 return a string representing an attribute for a file
444 ********************************************************************/
445 char *attrib_string(uint16 mode)
447 static fstring attrstr;
451 if (mode & aVOLID) fstrcat(attrstr,"V");
452 if (mode & aDIR) fstrcat(attrstr,"D");
453 if (mode & aARCH) fstrcat(attrstr,"A");
454 if (mode & aHIDDEN) fstrcat(attrstr,"H");
455 if (mode & aSYSTEM) fstrcat(attrstr,"S");
456 if (mode & aRONLY) fstrcat(attrstr,"R");
461 /****************************************************************************
462 make a file into unix format
463 ****************************************************************************/
464 void unix_format(char *fname)
466 string_replace(fname,'\\','/');
469 /****************************************************************************
470 make a file into dos format
471 ****************************************************************************/
472 void dos_format(char *fname)
474 string_replace(fname,'/','\\');
477 /*******************************************************************
478 show a smb message structure
479 ********************************************************************/
480 void show_msg(char *buf)
485 if (DEBUGLEVEL < 5) return;
487 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
489 (int)CVAL(buf,smb_com),
490 (int)CVAL(buf,smb_rcls),
491 (int)CVAL(buf,smb_reh),
492 (int)SVAL(buf,smb_err),
493 (int)CVAL(buf,smb_flg),
494 (int)SVAL(buf,smb_flg2)));
495 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
496 (int)SVAL(buf,smb_tid),
497 (int)SVAL(buf,smb_pid),
498 (int)SVAL(buf,smb_uid),
499 (int)SVAL(buf,smb_mid),
500 (int)CVAL(buf,smb_wct)));
502 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
504 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
505 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
508 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
510 DEBUG(5,("smb_bcc=%d\n",bcc));
512 if (DEBUGLEVEL < 10) return;
519 dump_data(10, smb_buf(buf), bcc);
521 /*******************************************************************
522 return the length of an smb packet
523 ********************************************************************/
524 int smb_len(char *buf)
526 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
529 /*******************************************************************
530 set the length of an smb packet
531 ********************************************************************/
532 void _smb_setlen(char *buf,int len)
535 buf[1] = (len&0x10000)>>16;
536 buf[2] = (len&0xFF00)>>8;
540 /*******************************************************************
541 set the length and marker of an smb packet
542 ********************************************************************/
543 void smb_setlen(char *buf,int len)
545 _smb_setlen(buf,len);
553 /*******************************************************************
554 setup the word count and byte count for a smb message
555 ********************************************************************/
556 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
559 bzero(buf + smb_size,num_words*2 + num_bytes);
560 CVAL(buf,smb_wct) = num_words;
561 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
562 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
563 return (smb_size + num_words*2 + num_bytes);
566 /*******************************************************************
567 return the number of smb words
568 ********************************************************************/
569 static int smb_numwords(char *buf)
571 return (CVAL(buf,smb_wct));
574 /*******************************************************************
575 return the size of the smb_buf region of a message
576 ********************************************************************/
577 int smb_buflen(char *buf)
579 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
582 /*******************************************************************
583 return a pointer to the smb_buf data area
584 ********************************************************************/
585 static int smb_buf_ofs(char *buf)
587 return (smb_size + CVAL(buf,smb_wct)*2);
590 /*******************************************************************
591 return a pointer to the smb_buf data area
592 ********************************************************************/
593 char *smb_buf(char *buf)
595 return (buf + smb_buf_ofs(buf));
598 /*******************************************************************
599 return the SMB offset into an SMB buffer
600 ********************************************************************/
601 int smb_offset(char *p,char *buf)
603 return(PTR_DIFF(p,buf+4) + chain_size);
608 /*******************************************************************
609 reduce a file name, removing .. elements.
610 ********************************************************************/
611 void dos_clean_name(char *s)
615 DEBUG(3,("dos_clean_name [%s]\n",s));
617 /* remove any double slashes */
618 string_sub(s, "\\\\", "\\");
620 while ((p = strstr(s,"\\..\\")) != NULL)
627 if ((p=strrchr(s,'\\')) != NULL)
634 trim_string(s,NULL,"\\..");
636 string_sub(s, "\\.\\", "\\");
639 /*******************************************************************
640 reduce a file name, removing .. elements.
641 ********************************************************************/
642 void unix_clean_name(char *s)
646 DEBUG(3,("unix_clean_name [%s]\n",s));
648 /* remove any double slashes */
649 string_sub(s, "//","/");
651 /* Remove leading ./ characters */
652 if(strncmp(s, "./", 2) == 0) {
653 trim_string(s, "./", NULL);
658 while ((p = strstr(s,"/../")) != NULL)
665 if ((p=strrchr(s,'/')) != NULL)
672 trim_string(s,NULL,"/..");
675 /*******************************************************************
676 reduce a file name, removing .. elements and checking that
677 it is below dir in the heirachy. This uses GetWd() and so must be run
678 on the system that has the referenced file system.
680 widelinks are allowed if widelinks is true
681 ********************************************************************/
683 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
693 BOOL relative = (*s != '/');
695 *dir2 = *wd = *base_name = *newname = 0;
700 /* can't have a leading .. */
701 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
703 DEBUG(3,("Illegal file name? (%s)\n",s));
713 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
715 /* remove any double slashes */
716 string_sub(s,"//","/");
718 pstrcpy(base_name,s);
719 p = strrchr(base_name,'/');
726 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
730 if (dos_ChDir(dir) != 0)
732 DEBUG(0,("couldn't chdir to %s\n",dir));
736 if (!dos_GetWd(dir2))
738 DEBUG(0,("couldn't getwd for %s\n",dir));
744 if (p && (p != base_name))
747 if (strcmp(p+1,".")==0)
749 if (strcmp(p+1,"..")==0)
753 if (dos_ChDir(base_name) != 0)
756 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
760 if (!dos_GetWd(newname))
763 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
767 if (p && (p != base_name))
769 pstrcat(newname,"/");
770 pstrcat(newname,p+1);
774 size_t l = strlen(dir2);
775 if (dir2[l-1] == '/')
778 if (strncmp(newname,dir2,l) != 0)
781 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
787 if (newname[l] == '/')
788 pstrcpy(s,newname + l + 1);
790 pstrcpy(s,newname+l);
801 DEBUG(3,("reduced to %s\n",s));
806 /****************************************************************************
808 ****************************************************************************/
809 static void expand_one(char *Mask,int len)
812 while ((p1 = strchr(Mask,'*')) != NULL)
814 int lfill = (len+1) - strlen(Mask);
818 memset(tmp+l1,'?',lfill);
819 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
824 /****************************************************************************
825 parse out a directory name from a path name. Assumes dos style filenames.
826 ****************************************************************************/
827 static void dirname_dos(char *path,char *buf)
829 split_at_last_component(path, buf, '\\', NULL);
833 /****************************************************************************
834 expand a wildcard expression, replacing *s with ?s
835 ****************************************************************************/
836 void expand_mask(char *Mask,BOOL doext)
843 BOOL absolute = (*Mask == '\\');
845 *mbeg = *mext = *dirpart = *filepart = 0;
847 /* parse the directory and filename */
848 if (strchr(Mask,'\\'))
849 dirname_dos(Mask,dirpart);
851 filename_dos(Mask,filepart);
853 pstrcpy(mbeg,filepart);
854 if ((p1 = strchr(mbeg,'.')) != NULL)
864 if (strlen(mbeg) > 8)
866 pstrcpy(mext,mbeg + 8);
872 pstrcpy(mbeg,"????????");
873 if ((*mext == 0) && doext && !hasdot)
876 if (strequal(mbeg,"*") && *mext==0)
884 pstrcpy(Mask,dirpart);
885 if (*dirpart || absolute) pstrcat(Mask,"\\");
890 DEBUG(6,("Mask expanded to [%s]\n",Mask));
895 /****************************************************************************
897 ****************************************************************************/
898 void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
905 if ((mode & aDIR) != 0)
908 memset(buf+1,' ',11);
909 if ((p = strchr(mask2,'.')) != NULL)
912 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
913 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
917 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
919 bzero(buf+21,DIR_STRUCT_SIZE-21);
921 put_dos_date(buf,22,date);
922 SSVAL(buf,26,size & 0xFFFF);
923 SSVAL(buf,28,(size >> 16)&0xFFFF);
924 StrnCpy(buf+30,fname,12);
927 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
931 /*******************************************************************
932 close the low 3 fd's and open dev/null in their place
933 ********************************************************************/
934 void close_low_fds(void)
938 close(0); close(1); close(2);
939 /* try and use up these file descriptors, so silly
940 library routines writing to stdout etc won't cause havoc */
942 fd = sys_open("/dev/null",O_RDWR,0);
943 if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
945 DEBUG(0,("Can't open /dev/null\n"));
949 DEBUG(0,("Didn't get file descriptor %d\n",i));
955 /****************************************************************************
956 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
960 ****************************************************************************/
961 int set_blocking(int fd, BOOL set)
965 #define FLAG_TO_SET O_NONBLOCK
968 #define FLAG_TO_SET O_NDELAY
970 #define FLAG_TO_SET FNDELAY
974 if((val = fcntl(fd, F_GETFL, 0)) == -1)
976 if(set) /* Turn blocking on - ie. clear nonblock flag */
980 return fcntl( fd, F_SETFL, val);
985 /*******************************************************************
986 find the difference in milliseconds between two struct timeval
988 ********************************************************************/
989 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
991 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
992 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
997 /****************************************************************************
998 transfer some data between two fd's
999 ****************************************************************************/
1000 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
1002 static char *buf=NULL;
1005 SMB_OFF_T total = 0;
1007 DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
1010 size = lp_readsize();
1011 size = MAX(size,1024);
1014 while (!buf && size>0) {
1015 buf = (char *)Realloc(buf,size+8);
1016 if (!buf) size /= 2;
1020 DEBUG(0,("Can't allocate transfer buffer!\n"));
1024 abuf = buf + (align%8);
1031 int s = (int)MIN(n,(SMB_OFF_T)size);
1036 if (header && (headlen >= MIN(s,1024))) {
1046 if (header && headlen > 0)
1048 ret = MIN(headlen,size);
1049 memcpy(buf1,header,ret);
1052 if (headlen <= 0) header = NULL;
1056 ret += read(infd,buf1+ret,s-ret);
1060 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
1061 if (ret2 > 0) total += ret2;
1062 /* if we can't write then dump excess data */
1064 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
1066 if (ret <= 0 || ret2 != ret)
1075 /****************************************************************************
1076 find a pointer to a netbios name
1077 ****************************************************************************/
1078 static char *name_ptr(char *buf,int ofs)
1080 unsigned char c = *(unsigned char *)(buf+ofs);
1082 if ((c & 0xC0) == 0xC0)
1086 memcpy(p,buf+ofs,2);
1089 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1096 /****************************************************************************
1097 extract a netbios name from a buf
1098 ****************************************************************************/
1099 int name_extract(char *buf,int ofs,char *name)
1101 char *p = name_ptr(buf,ofs);
1102 int d = PTR_DIFF(p,buf+ofs);
1104 if (d < -50 || d > 50) return(0);
1105 return(name_interpret(p,name));
1108 /****************************************************************************
1109 return the total storage length of a mangled name
1110 ****************************************************************************/
1111 int name_len(char *s1)
1113 /* NOTE: this argument _must_ be unsigned */
1114 unsigned char *s = (unsigned char *)s1;
1117 /* If the two high bits of the byte are set, return 2. */
1118 if (0xC0 == (*s & 0xC0))
1121 /* Add up the length bytes. */
1122 for (len = 1; (*s); s += (*s) + 1) {
1124 SMB_ASSERT(len < 80);
1131 /*******************************************************************
1132 sleep for a specified number of milliseconds
1133 ********************************************************************/
1137 struct timeval tval,t1,t2;
1144 tval.tv_sec = (t-tdiff)/1000;
1145 tval.tv_usec = 1000*((t-tdiff)%1000);
1149 sys_select(0,&fds,&tval);
1152 tdiff = TvalDiff(&t1,&t2);
1157 /*********************************************************
1158 * Recursive routine that is called by unix_mask_match.
1159 * Does the actual matching. This is the 'original code'
1160 * used by the unix matcher.
1161 *********************************************************/
1162 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
1166 for( p = regexp; *p && *str; ) {
1173 /* Look for a character matching
1174 the one after the '*' */
1177 return True; /* Automatic match */
1179 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
1181 if(unix_do_match(str,p,case_sig))
1195 if(toupper(*str) != toupper(*p))
1205 if (!*p && str[0] == '.' && str[1] == 0)
1208 if (!*str && *p == '?')
1210 while (*p == '?') p++;
1214 if(!*str && (*p == '*' && p[1] == '\0'))
1220 /*********************************************************
1221 * Routine to match a given string with a regexp - uses
1222 * simplified regexp that takes * and ? only. Case can be
1223 * significant or not.
1224 * This is the 'original code' used by the unix matcher.
1225 *********************************************************/
1227 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
1231 fstring ebase,eext,sbase,sext;
1235 /* Make local copies of str and regexp */
1236 StrnCpy(p1,regexp,sizeof(pstring)-1);
1237 StrnCpy(p2,str,sizeof(pstring)-1);
1239 if (!strchr(p2,'.')) {
1243 /* Remove any *? and ** as they are meaningless */
1244 for(p = p1; *p; p++)
1245 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
1246 (void)pstrcpy( &p[1], &p[2]);
1248 if (strequal(p1,"*")) return(True);
1250 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
1256 if ((p=strrchr(p1,'.'))) {
1265 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
1275 matched = unix_do_match(sbase,ebase,case_sig) &&
1276 (trans2 || unix_do_match(sext,eext,case_sig));
1278 DEBUG(8,("unix_mask_match returning %d\n", matched));
1283 /*********************************************************
1284 * Recursive routine that is called by mask_match.
1285 * Does the actual matching. Returns True if matched,
1286 * False if failed. This is the 'new' NT style matcher.
1287 *********************************************************/
1289 BOOL do_match(char *str, char *regexp, int case_sig)
1293 for( p = regexp; *p && *str; ) {
1300 /* Look for a character matching
1301 the one after the '*' */
1304 return True; /* Automatic match */
1306 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
1308 /* Now eat all characters that match, as
1309 we want the *last* character to match. */
1310 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
1312 str--; /* We've eaten the match char after the '*' */
1313 if(do_match(str,p,case_sig)) {
1330 if(toupper(*str) != toupper(*p)) {
1342 if (!*p && str[0] == '.' && str[1] == 0) {
1346 if (!*str && *p == '?') {
1352 if(!*str && (*p == '*' && p[1] == '\0')) {
1360 /*********************************************************
1361 * Routine to match a given string with a regexp - uses
1362 * simplified regexp that takes * and ? only. Case can be
1363 * significant or not.
1364 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
1365 * This is the new 'NT style' matcher.
1366 *********************************************************/
1368 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
1371 pstring t_pattern, t_filename, te_pattern, te_filename;
1372 fstring ebase,eext,sbase,sext;
1374 BOOL matched = False;
1376 /* Make local copies of str and regexp */
1377 pstrcpy(t_pattern,regexp);
1378 pstrcpy(t_filename,str);
1382 * Not sure if this is a good idea. JRA.
1384 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
1389 if (!strchr(t_filename,'.')) {
1390 pstrcat(t_filename,".");
1394 /* Remove any *? and ** as they are meaningless */
1395 string_sub(t_pattern, "*?", "*");
1396 string_sub(t_pattern, "**", "*");
1398 if (strequal(t_pattern,"*"))
1401 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
1405 * Match each component of the regexp, split up by '.'
1408 char *fp, *rp, *cp2, *cp1;
1409 BOOL last_wcard_was_star = False;
1410 int num_path_components, num_regexp_components;
1412 pstrcpy(te_pattern,t_pattern);
1413 pstrcpy(te_filename,t_filename);
1415 * Remove multiple "*." patterns.
1417 string_sub(te_pattern, "*.*.", "*.");
1418 num_regexp_components = count_chars(te_pattern, '.');
1419 num_path_components = count_chars(te_filename, '.');
1422 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
1424 if(num_regexp_components == 0)
1425 matched = do_match( te_filename, te_pattern, case_sig);
1427 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
1428 fp = strchr(cp2, '.');
1431 rp = strchr(cp1, '.');
1435 if(cp1[strlen(cp1)-1] == '*')
1436 last_wcard_was_star = True;
1438 last_wcard_was_star = False;
1440 if(!do_match(cp2, cp1, case_sig))
1443 cp1 = rp ? rp + 1 : NULL;
1444 cp2 = fp ? fp + 1 : "";
1446 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
1447 /* Eat the extra path components. */
1450 for(i = 0; i < num_path_components - num_regexp_components; i++) {
1451 fp = strchr(cp2, '.');
1455 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
1456 cp2 = fp ? fp + 1 : "";
1459 cp2 = fp ? fp + 1 : "";
1461 num_path_components -= i;
1464 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
1469 /* -------------------------------------------------
1470 * Behaviour of Win95
1471 * for 8.3 filenames and 8.3 Wildcards
1472 * -------------------------------------------------
1474 if (strequal (t_filename, ".")) {
1476 * Patterns: *.* *. ?. ? are valid
1479 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
1480 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
1482 } else if (strequal (t_filename, "..")) {
1484 * Patterns: *.* *. ?. ? *.? are valid
1487 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
1488 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
1489 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
1493 if ((p = strrchr (t_pattern, '.'))) {
1495 * Wildcard has a suffix.
1498 fstrcpy (ebase, t_pattern);
1500 fstrcpy (eext, p + 1);
1502 /* pattern ends in DOT: treat as if there is no DOT */
1504 if (strequal (ebase, "*"))
1509 * No suffix for wildcard.
1511 fstrcpy (ebase, t_pattern);
1515 p = strrchr (t_filename, '.');
1516 if (p && (p[1] == 0) ) {
1518 * Filename has an extension of '.' only.
1520 *p = 0; /* nuke dot at end of string */
1521 p = 0; /* and treat it as if there is no extension */
1526 * Filename has an extension.
1529 fstrcpy (sbase, t_filename);
1530 fstrcpy (sext, p + 1);
1532 matched = do_match(sbase, ebase, case_sig)
1533 && do_match(sext, eext, case_sig);
1535 /* pattern has no extension */
1536 /* Really: match complete filename with pattern ??? means exactly 3 chars */
1537 matched = do_match(str, ebase, case_sig);
1541 * Filename has no extension.
1543 fstrcpy (sbase, t_filename);
1546 /* pattern has extension */
1547 matched = do_match(sbase, ebase, case_sig)
1548 && do_match(sext, eext, case_sig);
1550 matched = do_match(sbase, ebase, case_sig);
1551 #ifdef EMULATE_WEIRD_W95_MATCHING
1553 * Even Microsoft has some problems
1554 * Behaviour Win95 -> local disk
1555 * is different from Win95 -> smb drive from Nt 4.0
1556 * This branch would reflect the Win95 local disk behaviour
1559 /* a? matches aa and a in w95 */
1560 fstrcat (sbase, ".");
1561 matched = do_match(sbase, ebase, case_sig);
1569 DEBUG(8,("mask_match returning %d\n", matched));
1574 /****************************************************************************
1575 become a daemon, discarding the controlling terminal
1576 ****************************************************************************/
1577 void become_daemon(void)
1583 /* detach from the terminal */
1586 #elif defined(TIOCNOTTY)
1588 int i = sys_open("/dev/tty", O_RDWR, 0);
1590 ioctl(i, (int) TIOCNOTTY, (char *)0);
1594 #endif /* HAVE_SETSID */
1596 /* Close fd's 0,1,2. Needed if started by rsh */
1601 /****************************************************************************
1602 put up a yes/no prompt
1603 ****************************************************************************/
1609 if (!fgets(ans,sizeof(ans)-1,stdin))
1612 if (*ans == 'y' || *ans == 'Y')
1620 /****************************************************************************
1621 set the length of a file from a filedescriptor.
1622 Returns 0 on success, -1 on failure.
1623 ****************************************************************************/
1624 int set_filelen(int fd, SMB_OFF_T len)
1626 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1627 extend a file with ftruncate. Provide alternate implementation
1630 #ifdef HAVE_FTRUNCATE_EXTEND
1631 return sys_ftruncate(fd, len);
1635 SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
1639 /* Do an fstat to see if the file is longer than
1640 the requested size (call ftruncate),
1641 or shorter, in which case seek to len - 1 and write 1
1643 if(sys_fstat(fd, &st)<0)
1647 if (S_ISFIFO(st.st_mode)) return 0;
1650 if(st.st_size == len)
1652 if(st.st_size > len)
1653 return sys_ftruncate(fd, len);
1655 if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
1657 if(write(fd, &c, 1)!=1)
1659 /* Seek to where we were */
1660 if(sys_lseek(fd, currpos, SEEK_SET) != currpos)
1668 /****************************************************************************
1669 this is a version of setbuffer() for those machines that only have setvbuf
1670 ****************************************************************************/
1671 void setbuffer(FILE *f,char *buf,int bufsize)
1673 setvbuf(f,buf,_IOFBF,bufsize);
1678 /****************************************************************************
1679 parse out a filename from a path name. Assumes dos style filenames.
1680 ****************************************************************************/
1681 static char *filename_dos(char *path,char *buf)
1683 char *p = strrchr(path,'\\');
1695 /****************************************************************************
1696 expand a pointer to be a particular size
1697 ****************************************************************************/
1698 void *Realloc(void *p,size_t size)
1704 DEBUG(5,("Realloc asked for 0 bytes\n"));
1709 ret = (void *)malloc(size);
1711 ret = (void *)realloc(p,size);
1716 smb_mem_write_info(ret, dbf);
1721 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
1727 /****************************************************************************
1728 get my own name and IP
1729 ****************************************************************************/
1730 BOOL get_myname(char *my_name,struct in_addr *ip)
1737 /* get my host name */
1738 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
1740 DEBUG(0,("gethostname failed\n"));
1745 if ((hp = Get_Hostbyname(hostname)) == 0)
1747 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
1753 /* split off any parts after an initial . */
1754 char *p = strchr(hostname,'.');
1757 fstrcpy(my_name,hostname);
1761 putip((char *)ip,(char *)hp->h_addr);
1767 /****************************************************************************
1768 true if two IP addresses are equal
1769 ****************************************************************************/
1770 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
1773 a1 = ntohl(ip1.s_addr);
1774 a2 = ntohl(ip2.s_addr);
1779 /****************************************************************************
1780 interpret a protocol description string, with a default
1781 ****************************************************************************/
1782 int interpret_protocol(char *str,int def)
1784 if (strequal(str,"NT1"))
1785 return(PROTOCOL_NT1);
1786 if (strequal(str,"LANMAN2"))
1787 return(PROTOCOL_LANMAN2);
1788 if (strequal(str,"LANMAN1"))
1789 return(PROTOCOL_LANMAN1);
1790 if (strequal(str,"CORE"))
1791 return(PROTOCOL_CORE);
1792 if (strequal(str,"COREPLUS"))
1793 return(PROTOCOL_COREPLUS);
1794 if (strequal(str,"CORE+"))
1795 return(PROTOCOL_COREPLUS);
1797 DEBUG(0,("Unrecognised protocol level %s\n",str));
1803 /****************************************************************************
1804 interpret an internet address or name into an IP address in 4 byte form
1805 ****************************************************************************/
1806 uint32 interpret_addr(char *str)
1811 BOOL pure_address = True;
1813 if (strcmp(str,"0.0.0.0") == 0) return(0);
1814 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
1816 for (i=0; pure_address && str[i]; i++)
1817 if (!(isdigit((int)str[i]) || str[i] == '.'))
1818 pure_address = False;
1820 /* if it's in the form of an IP address then get the lib to interpret it */
1822 res = inet_addr(str);
1824 /* otherwise assume it's a network name of some sort and use
1826 if ((hp = Get_Hostbyname(str)) == 0) {
1827 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
1830 if(hp->h_addr == NULL) {
1831 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
1834 putip((char *)&res,(char *)hp->h_addr);
1837 if (res == (uint32)-1) return(0);
1842 /*******************************************************************
1843 a convenient addition to interpret_addr()
1844 ******************************************************************/
1845 struct in_addr *interpret_addr2(char *str)
1847 static struct in_addr ret;
1848 uint32 a = interpret_addr(str);
1853 /*******************************************************************
1854 check if an IP is the 0.0.0.0
1855 ******************************************************************/
1856 BOOL zero_ip(struct in_addr ip)
1859 putip((char *)&a,(char *)&ip);
1864 /*******************************************************************
1865 matchname - determine if host name matches IP address
1866 ******************************************************************/
1867 BOOL matchname(char *remotehost,struct in_addr addr)
1872 if ((hp = Get_Hostbyname(remotehost)) == 0) {
1873 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
1878 * Make sure that gethostbyname() returns the "correct" host name.
1879 * Unfortunately, gethostbyname("localhost") sometimes yields
1880 * "localhost.domain". Since the latter host name comes from the
1881 * local DNS, we just have to trust it (all bets are off if the local
1882 * DNS is perverted). We always check the address list, though.
1885 if (strcasecmp(remotehost, hp->h_name)
1886 && strcasecmp(remotehost, "localhost")) {
1887 DEBUG(0,("host name/name mismatch: %s != %s",
1888 remotehost, hp->h_name));
1892 /* Look up the host address in the address list we just got. */
1893 for (i = 0; hp->h_addr_list[i]; i++) {
1894 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
1899 * The host name does not map to the original host address. Perhaps
1900 * someone has compromised a name server. More likely someone botched
1901 * it, but that could be dangerous, too.
1904 DEBUG(0,("host name/address mismatch: %s != %s",
1905 inet_ntoa(addr), hp->h_name));
1910 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1911 /******************************************************************
1912 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1913 Based on a fix from <Thomas.Hepper@icem.de>.
1914 *******************************************************************/
1916 static void strip_mount_options( pstring *str)
1921 while(*p && !isspace(*p))
1923 while(*p && isspace(*p))
1928 pstrcpy(tmp_str, p);
1929 pstrcpy(*str, tmp_str);
1934 /*******************************************************************
1935 Patch from jkf@soton.ac.uk
1936 Split Luke's automount_server into YP lookup and string splitter
1937 so can easily implement automount_path().
1938 As we may end up doing both, cache the last YP result.
1939 *******************************************************************/
1941 #ifdef WITH_NISPLUS_HOME
1942 static char *automount_lookup(char *user_name)
1944 static fstring last_key = "";
1945 static pstring last_value = "";
1947 char *nis_map = (char *)lp_nis_home_map_name();
1949 char nis_domain[NIS_MAXNAMELEN + 1];
1950 char buffer[NIS_MAXATTRVAL + 1];
1955 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
1956 nis_domain[NIS_MAXNAMELEN] = '\0';
1958 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
1960 if (strcmp(user_name, last_key))
1962 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
1963 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1965 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
1967 if (result->status != NIS_SUCCESS)
1969 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1970 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1974 object = result->objects.objects_val;
1975 if (object->zo_data.zo_type == ENTRY_OBJ)
1977 entry = &object->zo_data.objdata_u.en_data;
1978 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1979 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1981 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1982 string_sub(last_value, "&", user_name);
1983 fstrcpy(last_key, user_name);
1987 nis_freeresult(result);
1990 strip_mount_options(&last_value);
1992 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1995 #else /* WITH_NISPLUS_HOME */
1996 static char *automount_lookup(char *user_name)
1998 static fstring last_key = "";
1999 static pstring last_value = "";
2001 int nis_error; /* returned by yp all functions */
2002 char *nis_result; /* yp_match inits this */
2003 int nis_result_len; /* and set this */
2004 char *nis_domain; /* yp_get_default_domain inits this */
2005 char *nis_map = (char *)lp_nis_home_map_name();
2007 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
2009 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
2013 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
2015 if (!strcmp(user_name, last_key))
2017 nis_result = last_value;
2018 nis_result_len = strlen(last_value);
2023 if ((nis_error = yp_match(nis_domain, nis_map,
2024 user_name, strlen(user_name),
2025 &nis_result, &nis_result_len)) != 0)
2027 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
2028 yperr_string(nis_error), user_name, nis_map));
2030 if (!nis_error && nis_result_len >= sizeof(pstring))
2032 nis_result_len = sizeof(pstring)-1;
2034 fstrcpy(last_key, user_name);
2035 strncpy(last_value, nis_result, nis_result_len);
2036 last_value[nis_result_len] = '\0';
2039 strip_mount_options(&last_value);
2041 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
2044 #endif /* WITH_NISPLUS_HOME */
2047 /*******************************************************************
2048 Patch from jkf@soton.ac.uk
2049 This is Luke's original function with the NIS lookup code
2050 moved out to a separate function.
2051 *******************************************************************/
2052 static char *automount_server(char *user_name)
2054 static pstring server_name;
2056 /* use the local machine name as the default */
2057 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2058 pstrcpy(server_name, local_machine);
2060 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2062 if (lp_nis_home_map())
2064 int home_server_len;
2065 char *automount_value = automount_lookup(user_name);
2066 home_server_len = strcspn(automount_value,":");
2067 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
2068 if (home_server_len > sizeof(pstring))
2070 home_server_len = sizeof(pstring);
2072 strncpy(server_name, automount_value, home_server_len);
2073 server_name[home_server_len] = '\0';
2077 DEBUG(4,("Home server: %s\n", server_name));
2082 /*******************************************************************
2083 Patch from jkf@soton.ac.uk
2084 Added this to implement %p (NIS auto-map version of %H)
2085 *******************************************************************/
2086 static char *automount_path(char *user_name)
2088 static pstring server_path;
2090 /* use the passwd entry as the default */
2091 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2092 /* pstrcpy() copes with get_home_dir() returning NULL */
2093 pstrcpy(server_path, get_home_dir(user_name));
2095 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2097 if (lp_nis_home_map())
2099 char *home_path_start;
2100 char *automount_value = automount_lookup(user_name);
2101 home_path_start = strchr(automount_value,':');
2102 if (home_path_start != NULL)
2104 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
2105 home_path_start?(home_path_start+1):""));
2106 pstrcpy(server_path, home_path_start+1);
2111 DEBUG(4,("Home server path: %s\n", server_path));
2117 /*******************************************************************
2118 sub strings with useful parameters
2119 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
2120 Paul Rippin <pr3245@nopc.eurostat.cec.be>
2121 ********************************************************************/
2122 void standard_sub_basic(char *str)
2126 struct passwd *pass;
2127 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
2129 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
2135 if ((pass = Get_Pwnam(username,False))!=NULL)
2137 string_sub(p,"%G",gidtoname(pass->pw_gid));
2145 case 'N' : string_sub(p,"%N", automount_server(username)); break;
2146 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
2147 case 'L' : string_sub(p,"%L", local_machine); break;
2148 case 'M' : string_sub(p,"%M", client_name(Client)); break;
2149 case 'R' : string_sub(p,"%R", remote_proto); break;
2150 case 'T' : string_sub(p,"%T", timestring()); break;
2151 case 'U' : string_sub(p,"%U", username); break;
2152 case 'a' : string_sub(p,"%a", remote_arch); break;
2155 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
2156 string_sub(p,"%d", pidstr);
2159 case 'h' : string_sub(p,"%h", myhostname); break;
2160 case 'm' : string_sub(p,"%m", remote_machine); break;
2161 case 'v' : string_sub(p,"%v", VERSION); break;
2162 case '$' : /* Expand environment variables */
2164 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
2175 if ((q = strchr(p,')')) == NULL)
2177 DEBUG(0,("standard_sub_basic: Unterminated environment \
2178 variable [%s]\n", p));
2184 copylen = MIN((q-r),(sizeof(envname)-1));
2185 strncpy(envname,r,copylen);
2186 envname[copylen] = '\0';
2188 if ((envval = getenv(envname)) == NULL)
2190 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
2196 copylen = MIN((q+1-p),(sizeof(envname)-1));
2197 strncpy(envname,p,copylen);
2198 envname[copylen] = '\0';
2199 string_sub(p,envname,envval);
2202 case '\0': p++; break; /* don't run off end if last character is % */
2203 default : p+=2; break;
2210 /****************************************************************************
2211 do some standard substitutions in a string
2212 ****************************************************************************/
2213 void standard_sub(connection_struct *conn,char *str)
2217 for (s=str; (p=strchr(s, '%'));s=p)
2222 if ((home = get_home_dir(conn->user)) != NULL) {
2223 string_sub(p,"%H",home);
2229 /* Patch from jkf@soton.ac.uk Left the %N (NIS
2230 * server name) in standard_sub_basic as it is
2231 * a feature for logon servers, hence uses the
2232 * username. The %p (NIS server path) code is
2233 * here as it is used instead of the default
2234 * "path =" string in [homes] and so needs the
2235 * service name, not the username. */
2236 case 'p': string_sub(p,"%p", automount_path(lp_servicename(SNUM(conn)))); break;
2237 case 'P': string_sub(p,"%P",conn->connectpath); break;
2238 case 'S': string_sub(p,"%S", lp_servicename(SNUM(conn))); break;
2239 case 'g': string_sub(p,"%g", gidtoname(conn->gid)); break;
2240 case 'u': string_sub(p,"%u", conn->user); break;
2242 case '\0': p++; break; /* don't run off the end of the string */
2243 default : p+=2; break;
2247 standard_sub_basic(str);
2252 /*******************************************************************
2253 are two IPs on the same subnet?
2254 ********************************************************************/
2255 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
2257 uint32 net1,net2,nmask;
2259 nmask = ntohl(mask.s_addr);
2260 net1 = ntohl(ip1.s_addr);
2261 net2 = ntohl(ip2.s_addr);
2263 return((net1 & nmask) == (net2 & nmask));
2267 /****************************************************************************
2268 a wrapper for gethostbyname() that tries with all lower and all upper case
2269 if the initial name fails
2270 ****************************************************************************/
2271 struct hostent *Get_Hostbyname(const char *name)
2273 char *name2 = strdup(name);
2274 struct hostent *ret;
2278 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
2284 * This next test is redundent and causes some systems (with
2285 * broken isalnum() calls) problems.
2290 if (!isalnum(*name2))
2297 ret = sys_gethostbyname(name2);
2304 /* try with all lowercase */
2306 ret = sys_gethostbyname(name2);
2313 /* try with all uppercase */
2315 ret = sys_gethostbyname(name2);
2322 /* nothing works :-( */
2328 /****************************************************************************
2329 check if a process exists. Does this work on all unixes?
2330 ****************************************************************************/
2332 BOOL process_exists(int pid)
2334 return(kill(pid,0) == 0 || errno != ESRCH);
2338 /****************************************************************************
2339 Setup the groups a user belongs to.
2340 ****************************************************************************/
2341 int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
2345 gid_t *groups = NULL;
2347 if (-1 == initgroups(user,gid))
2351 DEBUG(0,("Unable to initgroups!\n"));
2352 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2354 DEBUG(0,("This is probably a problem with the account %s\n", user));
2360 ngroups = sys_getgroups(0,&grp);
2366 if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
2368 DEBUG(0,("get_unixgroups malloc fail !\n"));
2372 ngroups = sys_getgroups(ngroups,groups);
2374 (*p_ngroups) = ngroups;
2375 (*p_groups) = groups;
2377 DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
2378 for (i = 0; i < ngroups; i++ )
2380 DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
2382 DEBUG( 3, ( "\n" ) );
2387 /****************************************************************************
2388 get all unix groups. copying group members is hideous on memory, so it's
2389 NOT done here. however, names of unix groups _are_ string-allocated so
2390 free_unix_grps() must be called.
2391 ****************************************************************************/
2392 BOOL get_unix_grps(int *p_ngroups, struct group **p_groups)
2396 DEBUG(10,("get_unix_grps\n"));
2398 if (p_ngroups == NULL || *p_groups == NULL)
2408 while ((grp = getgrent()) != NULL)
2410 struct group *copy_grp;
2412 (*p_groups) = (struct group*)Realloc((*p_groups), (size_t)((*p_ngroups)+1) * sizeof(struct group));
2413 if ((*p_groups) == NULL)
2421 copy_grp = &(*p_groups)[*p_ngroups];
2422 memcpy(copy_grp, grp, sizeof(*grp));
2423 copy_grp->gr_name = strdup(copy_grp->gr_name);
2424 copy_grp->gr_mem = NULL;
2431 DEBUG(10,("get_unix_grps: %d groups\n", (*p_ngroups)));
2435 /****************************************************************************
2436 free memory associated with unix groups.
2437 ****************************************************************************/
2438 void free_unix_grps(int ngroups, struct group *p_groups)
2442 if (p_groups == NULL)
2447 for (i = 0; i < ngroups; i++)
2449 if (p_groups[i].gr_name != NULL)
2451 free(p_groups[i].gr_name);
2458 /*******************************************************************
2459 turn a uid into a user name
2460 ********************************************************************/
2461 char *uidtoname(uid_t uid)
2463 static char name[40];
2464 struct passwd *pass = getpwuid(uid);
2465 if (pass) return(pass->pw_name);
2466 slprintf(name, sizeof(name) - 1, "%d",(int)uid);
2471 /*******************************************************************
2472 turn a gid into a group name
2473 ********************************************************************/
2475 char *gidtoname(gid_t gid)
2477 static char name[40];
2478 struct group *grp = getgrgid(gid);
2479 if (grp) return(grp->gr_name);
2480 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
2484 /*******************************************************************
2485 turn a group name into a gid
2486 ********************************************************************/
2488 BOOL nametogid(const char *name, gid_t *gid)
2490 struct group *grp = getgrnam(name);
2496 else if (isdigit(name[0]))
2498 *gid = (gid_t)get_number(name);
2507 /*******************************************************************
2508 turn a user name into a uid
2509 ********************************************************************/
2510 BOOL nametouid(const char *name, uid_t *uid)
2512 struct passwd *pass = Get_Pwnam(name, False);
2515 *uid = pass->pw_uid;
2518 else if (isdigit(name[0]))
2520 *uid = (uid_t)get_number(name);
2529 /*******************************************************************
2530 something really nasty happened - panic!
2531 ********************************************************************/
2532 void smb_panic(char *why)
2534 char *cmd = lp_panic_action();
2538 DEBUG(0,("PANIC: %s\n", why));
2544 /*******************************************************************
2545 a readdir wrapper which just returns the file name
2546 ********************************************************************/
2547 char *readdirname(DIR *p)
2552 if (!p) return(NULL);
2554 ptr = (struct dirent *)readdir(p);
2555 if (!ptr) return(NULL);
2557 dname = ptr->d_name;
2560 if (telldir(p) < 0) return(NULL);
2563 #ifdef HAVE_BROKEN_READDIR
2564 /* using /usr/ucb/cc is BAD */
2570 memcpy(buf, dname, NAMLEN(ptr)+1);
2577 /*******************************************************************
2578 Utility function used to decide if the last component
2579 of a path matches a (possibly wildcarded) entry in a namelist.
2580 ********************************************************************/
2582 BOOL is_in_path(char *name, name_compare_entry *namelist)
2584 pstring last_component;
2587 DEBUG(8, ("is_in_path: %s\n", name));
2589 /* if we have no list it's obviously not in the path */
2590 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
2592 DEBUG(8,("is_in_path: no name list.\n"));
2596 /* Get the last component of the unix name. */
2597 p = strrchr(name, '/');
2598 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
2599 last_component[sizeof(last_component)-1] = '\0';
2601 for(; namelist->name != NULL; namelist++)
2603 if(namelist->is_wild)
2606 * Look for a wildcard match. Use the old
2607 * 'unix style' mask match, rather than the
2610 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
2612 DEBUG(8,("is_in_path: mask match succeeded\n"));
2618 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
2619 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
2621 DEBUG(8,("is_in_path: match succeeded\n"));
2626 DEBUG(8,("is_in_path: match not found\n"));
2631 /*******************************************************************
2632 Strip a '/' separated list into an array of
2633 name_compare_enties structures suitable for
2634 passing to is_in_path(). We do this for
2635 speed so we can pre-parse all the names in the list
2636 and don't do it for each call to is_in_path().
2637 namelist is modified here and is assumed to be
2638 a copy owned by the caller.
2639 We also check if the entry contains a wildcard to
2640 remove a potentially expensive call to mask_match
2642 ********************************************************************/
2644 void set_namearray(name_compare_entry **ppname_array, char *namelist)
2647 char *nameptr = namelist;
2648 int num_entries = 0;
2651 (*ppname_array) = NULL;
2653 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
2656 /* We need to make two passes over the string. The
2657 first to count the number of elements, the second
2662 if ( *nameptr == '/' )
2664 /* cope with multiple (useless) /s) */
2668 /* find the next / */
2669 name_end = strchr(nameptr, '/');
2671 /* oops - the last check for a / didn't find one. */
2672 if (name_end == NULL)
2675 /* next segment please */
2676 nameptr = name_end + 1;
2680 if(num_entries == 0)
2683 if(( (*ppname_array) = (name_compare_entry *)malloc(
2684 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
2686 DEBUG(0,("set_namearray: malloc fail\n"));
2690 /* Now copy out the names */
2695 if ( *nameptr == '/' )
2697 /* cope with multiple (useless) /s) */
2701 /* find the next / */
2702 if ((name_end = strchr(nameptr, '/')) != NULL)
2707 /* oops - the last check for a / didn't find one. */
2708 if(name_end == NULL)
2711 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
2712 (strchr( nameptr, '*')!=NULL));
2713 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
2715 DEBUG(0,("set_namearray: malloc fail (1)\n"));
2719 /* next segment please */
2720 nameptr = name_end + 1;
2724 (*ppname_array)[i].name = NULL;
2729 /****************************************************************************
2730 routine to free a namearray.
2731 ****************************************************************************/
2733 void free_namearray(name_compare_entry *name_array)
2738 if(name_array->name != NULL)
2739 free(name_array->name);
2741 free((char *)name_array);
2744 /****************************************************************************
2745 routine to do file locking
2746 ****************************************************************************/
2747 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2750 SMB_STRUCT_FLOCK lock;
2753 if(lp_ole_locking_compat()) {
2754 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
2755 SMB_OFF_T mask = (mask2<<2);
2757 /* make sure the count is reasonable, we might kill the lockd otherwise */
2760 /* the offset is often strange - remove 2 of its bits if either of
2761 the top two bits are set. Shift the top ones by two bits. This
2762 still allows OLE2 apps to operate, but should stop lockd from
2764 if ((offset & mask) != 0)
2765 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
2767 SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
2768 SMB_OFF_T mask = (mask2<<1);
2769 SMB_OFF_T neg_mask = ~mask;
2771 /* interpret negative counts as large numbers */
2775 /* no negative offsets */
2779 /* count + offset must be in range */
2780 while ((offset < 0 || (offset + count < 0)) && mask)
2783 mask = ((mask >> 1) & neg_mask);
2787 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
2790 lock.l_whence = SEEK_SET;
2791 lock.l_start = offset;
2797 ret = fcntl(fd,op,&lock);
2802 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
2803 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
2804 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
2806 /* 32 bit NFS file system, retry with smaller offset */
2808 lock.l_len = count & 0xffffffff;
2809 ret = fcntl(fd,op,&lock);
2813 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
2816 if (op == SMB_F_GETLK)
2819 (lock.l_type != F_UNLCK) &&
2820 (lock.l_pid != 0) &&
2821 (lock.l_pid != getpid()))
2823 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
2827 /* it must be not locked or locked by me */
2831 /* a lock set or unset */
2834 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2835 (double)offset,(double)count,op,type,strerror(errno)));
2837 /* perhaps it doesn't support this sort of locking?? */
2838 if (errno == EINVAL)
2840 DEBUG(3,("locking not supported? returning True\n"));
2847 /* everything went OK */
2848 DEBUG(8,("Lock call successful\n"));
2856 /*******************************************************************
2857 is the name specified one of my netbios names
2858 returns true is it is equal, false otherwise
2859 ********************************************************************/
2860 BOOL is_myname(char *s)
2865 for (n=0; my_netbios_names[n]; n++) {
2866 if (strequal(my_netbios_names[n], s))
2869 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2873 /*******************************************************************
2874 set the horrid remote_arch string based on an enum.
2875 ********************************************************************/
2876 void set_remote_arch(enum remote_arch_types type)
2882 fstrcpy(remote_arch, "WfWg");
2885 fstrcpy(remote_arch, "OS2");
2888 fstrcpy(remote_arch, "Win95");
2891 fstrcpy(remote_arch, "WinNT");
2894 fstrcpy(remote_arch,"Samba");
2897 ra_type = RA_UNKNOWN;
2898 fstrcpy(remote_arch, "UNKNOWN");
2903 /*******************************************************************
2904 Get the remote_arch type.
2905 ********************************************************************/
2906 enum remote_arch_types get_remote_arch(void)
2912 /*******************************************************************
2913 align a pointer to a multiple of 2 bytes
2914 ********************************************************************/
2915 char *align2(char *q, char *base)
2924 void out_ascii(FILE *f, unsigned char *buf,int len)
2929 fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
2933 void out_data(FILE *f,char *buf1,int len, int per_line)
2935 unsigned char *buf = (unsigned char *)buf1;
2942 fprintf(f, "[%03X] ",i);
2945 fprintf(f, "%02X ",(int)buf[i]);
2947 if (i%(per_line/2) == 0) fprintf(f, " ");
2948 if (i%per_line == 0)
2950 out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
2951 out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
2952 if (i<len) fprintf(f, "[%03X] ",i);
2955 if ((i%per_line) != 0)
2959 n = per_line - (i%per_line);
2961 if (n>(per_line/2)) fprintf(f, " ");
2966 n = MIN(per_line/2,i%per_line);
2967 out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " ");
2968 n = (i%per_line) - n;
2969 if (n>0) out_ascii(f,&buf[i-n],n);
2974 void print_asc(int level, unsigned char *buf,int len)
2978 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2981 void dump_data(int level,char *buf1,int len)
2983 unsigned char *buf = (unsigned char *)buf1;
2987 DEBUG(level,("[%03X] ",i));
2989 DEBUG(level,("%02X ",(int)buf[i]));
2991 if (i%8 == 0) DEBUG(level,(" "));
2993 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
2994 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
2995 if (i<len) DEBUG(level,("[%03X] ",i));
3003 if (n>8) DEBUG(level,(" "));
3004 while (n--) DEBUG(level,(" "));
3007 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
3009 if (n>0) print_asc(level,&buf[i-n],n);
3010 DEBUG(level,("\n"));
3014 char *tab_depth(int depth)
3016 static pstring spaces;
3017 memset(spaces, ' ', depth * 4);
3018 spaces[depth * 4] = 0;
3022 /*****************************************************************************
3023 * Provide a checksum on a string
3025 * Input: s - the null-terminated character string for which the checksum
3026 * will be calculated.
3028 * Output: The checksum value calculated for s.
3030 * ****************************************************************************
3032 int str_checksum(const char *s)
3040 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
3045 } /* str_checksum */
3049 /*****************************************************************
3050 zero a memory area then free it. Used to catch bugs faster
3051 *****************************************************************/
3052 void zero_free(void *p, size_t size)
3059 /*****************************************************************
3060 set our open file limit to a requested max and return the limit
3061 *****************************************************************/
3062 int set_maxfiles(int requested_max)
3064 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
3066 getrlimit(RLIMIT_NOFILE, &rlp);
3067 /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
3068 * account for the extra fd we need
3069 * as well as the log files and standard
3071 rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
3072 setrlimit(RLIMIT_NOFILE, &rlp);
3073 getrlimit(RLIMIT_NOFILE, &rlp);
3074 return rlp.rlim_cur;
3077 * No way to know - just guess...
3079 return requested_max;
3084 /*****************************************************************
3085 splits out the last subkey of a key
3086 *****************************************************************/
3087 void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name)
3089 split_at_last_component(full_keyname, key_name, '\\', subkey_name);
3092 /*****************************************************************
3093 splits out the start of the key (HKLM or HKU) and the rest of the key
3094 *****************************************************************/
3095 BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
3099 if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
3106 DEBUG(10, ("reg_split_key: hive %s\n", tmp));
3108 if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
3110 (*reg_type) = HKEY_LOCAL_MACHINE;
3112 else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
3114 (*reg_type) = HKEY_USERS;
3118 DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
3122 if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
3124 fstrcpy(key_name, tmp);
3131 DEBUG(10, ("reg_split_key: name %s\n", key_name));
3136 /****************************************************************************
3137 become the specified uid - permanently !
3138 ****************************************************************************/
3139 BOOL become_user_permanently(uid_t uid, gid_t gid)
3141 /* now completely lose our privilages. This is a fairly paranoid
3142 way of doing it, but it does work on all systems that I know of */
3144 #ifdef HAVE_SETRESUID
3146 * Firstly ensure all our uids are set to root.
3152 * Now ensure we change all our gids.
3154 setresgid(gid,gid,gid);
3157 * Now ensure all the uids are the user.
3159 setresuid(uid,uid,uid);
3162 * Firstly ensure all our uids are set to root.
3168 * Now ensure we change all our gids.
3174 * Now ensure all the uids are the user.
3180 if (getuid() != uid || geteuid() != uid ||
3181 getgid() != gid || getegid() != gid) {
3182 /* We failed to lose our privilages. */