2 Unix SMB/Netbios implementation.
4 Samba utility functions
6 Copyright (C) Andrew Tridgell 1992-1998
8 Copyright (C) 2011-2018
9 Free Software Foundation, Inc.
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
30 #ifdef WITH_NISPLUS_HOME
31 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
33 * The following lines are needed due to buggy include files
34 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
35 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
36 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
37 * an enum in /usr/include/rpcsvc/nis.h.
44 #if defined(GROUP_OBJ)
48 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
50 #include <rpcsvc/nis.h>
52 #else /* !WITH_NISPLUS_HOME */
54 #include "rpcsvc/ypclnt.h"
56 #endif /* WITH_NISPLUS_HOME */
57 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
61 #undef Realloc /* SSLeay defines this and samba has a function of this name */
64 extern int DEBUGLEVEL
;
66 int Protocol
= PROTOCOL_COREPLUS
;
69 /* a default finfo structure to ensure all fields are sensible */
70 file_info
const def_finfo
= { -1, 0, 0, 0, 0, 0, 0, "" };
72 /* the client file descriptor */
75 /* this is used by the chaining code */
76 const int chain_size
= 0;
79 case handling on filenames
81 const int case_default
= CASE_LOWER
;
84 /* the following control case operations - they are put here so the
85 client can link easily */
88 BOOL use_mangled_map
= False
;
89 BOOL short_case_preserve
;
93 static const char *remote_machine
= "";
94 static const char *local_machine
= "";
95 static const char *remote_arch
= "UNKNOWN";
97 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
99 static const char *remote_proto
= "UNKNOWN";
100 pstring myhostname
= "";
101 pstring user_socket_options
= "";
103 static const char sesssetup_user
[] = "";
104 static const char *const samlogon_user
= "";
106 const BOOL sam_logon_in_ssb
= False
;
108 pstring global_myname
= "";
110 char **my_netbios_names
;
114 /****************************************************************************
115 find a suitable temporary directory. The result should be copied immediately
116 as it may be overwritten by a subsequent call
117 ****************************************************************************/
122 if ((p
= getenv ("MC_TMPDIR")) || (p
= getenv ("TMPDIR")))
129 /****************************************************************************
130 determine whether we are in the specified group
131 ****************************************************************************/
134 in_group (gid_t group
, gid_t current_gid
, int ngroups
, gid_t
* groups
)
138 if (group
== current_gid
)
141 for (i
= 0; i
< ngroups
; i
++)
142 if (group
== groups
[i
])
149 /****************************************************************************
150 like atoi but gets the value up to the separater character
151 ****************************************************************************/
153 Atoic (char *p
, int *n
, char *c
)
155 if (!isdigit ((int) *p
))
157 DEBUG (5, ("Atoic: malformed number\n"));
163 while ((*p
) && isdigit ((int) *p
))
168 if (strchr (c
, *p
) == NULL
)
170 DEBUG (5, ("Atoic: no separator characters (%s) not found\n", c
));
177 /*************************************************************************
178 reads a list of numbers
179 *************************************************************************/
181 get_numlist (char *p
, uint32
** num
, int *count
)
185 if (num
== NULL
|| count
== NULL
)
193 while ((p
= Atoic (p
, &val
, ":,")) != NULL
&& (*p
) != ':')
195 (*num
) = Realloc ((*num
), ((*count
) + 1) * sizeof (uint32
));
200 (*num
)[(*count
)] = val
;
208 /*******************************************************************
209 copy an IP address from one buffer to another
210 ********************************************************************/
212 putip (void *dest
, void *src
)
214 memcpy (dest
, src
, 4);
218 #define TRUNCATE_NETBIOS_NAME 1
220 /*******************************************************************
221 convert, possibly using a stupid microsoft-ism which has destroyed
222 the transport independence of netbios (for CIFS vendors that usually
223 use the Win95-type methods, not for NT to NT communication, which uses
224 DCE/RPC and therefore full-length unicode strings...) a dns name into
227 the netbios name (NOT necessarily null-terminated) is truncated to 15
230 ******************************************************************/
232 dns_to_netbios_name (char *dns_name
)
234 static char netbios_name
[16];
236 StrnCpy (netbios_name
, dns_name
, 15);
237 netbios_name
[15] = 0;
239 #ifdef TRUNCATE_NETBIOS_NAME
240 /* ok. this is because of a stupid microsoft-ism. if the called host
241 name contains a '.', microsoft clients expect you to truncate the
242 netbios name up to and including the '.' this even applies, by
243 mistake, to workgroup (domain) names, which is _really_ daft.
245 for (i
= 15; i
>= 0; i
--)
247 if (netbios_name
[i
] == '.')
253 #endif /* TRUNCATE_NETBIOS_NAME */
259 /****************************************************************************
260 interpret the weird netbios "name". Return the name type
261 ****************************************************************************/
263 name_interpret (char *in
, char *out
)
266 int len
= (*in
++) / 2;
270 if (len
> 30 || len
< 1)
275 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P')
280 *out
= ((in
[0] - 'A') << 4) + (in
[1] - 'A');
288 /* Handle any scope names */
291 *out
++ = '.'; /* Scope names are separated by periods */
292 len
= *(unsigned char *) in
++;
293 StrnCpy (out
, in
, len
);
303 /****************************************************************************
304 mangle a name into netbios format
306 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
307 ****************************************************************************/
309 name_mangle (char *In
, char *Out
, char name_type
)
316 extern pstring global_scope
;
318 /* Safely copy the input string, In, into buf[]. */
319 (void) memset (buf
, 0, 20);
320 if (strcmp (In
, "*") == 0)
323 (void) slprintf (buf
, sizeof (buf
) - 1, "%-15.15s%c", In
, name_type
);
325 /* Place the length of the first field into the output buffer. */
329 /* Now convert the name to the rfc1001/1002 format. */
330 for (i
= 0; i
< 16; i
++)
332 c
= toupper (buf
[i
]);
333 p
[i
* 2] = ((c
>> 4) & 0x000F) + 'A';
334 p
[(i
* 2) + 1] = (c
& 0x000F) + 'A';
339 /* Add the scope string. */
340 for (i
= 0, len
= 0;; i
++, len
++)
342 switch (global_scope
[i
])
348 return (name_len (Out
));
355 p
[len
+ 1] = global_scope
[i
];
360 return (name_len (Out
));
363 /*******************************************************************
364 check if a file exists
365 ********************************************************************/
367 file_exist (char *fname
, SMB_STRUCT_STAT
* sbuf
)
373 if (sys_stat (fname
, sbuf
) != 0)
376 return (S_ISREG (sbuf
->st_mode
));
379 /*******************************************************************
380 check a files mod time
381 ********************************************************************/
383 file_modtime (char *fname
)
387 if (sys_stat (fname
, &st
) != 0)
390 return (st
.st_mtime
);
394 /*******************************************************************
395 check if a directory exists
396 ********************************************************************/
398 directory_exist (char *dname
, SMB_STRUCT_STAT
* st
)
406 if (sys_stat (dname
, st
) != 0)
409 ret
= S_ISDIR (st
->st_mode
);
415 /*******************************************************************
416 returns the size in bytes of the named file
417 ********************************************************************/
419 file_size (char *file_name
)
423 if (sys_stat (file_name
, &buf
) != 0)
424 return (SMB_OFF_T
) - 1;
425 return (buf
.st_size
);
429 /*******************************************************************
430 return a string representing an attribute for a file
431 ********************************************************************/
433 attrib_string (uint16 mode
)
435 static char attrstr
[7];
459 /****************************************************************************
460 make a file into unix format
461 ****************************************************************************/
463 unix_format (char *fname
)
465 string_replace (fname
, '\\', '/');
468 /****************************************************************************
469 make a file into dos format
470 ****************************************************************************/
472 dos_format (char *fname
)
474 string_replace (fname
, '/', '\\');
477 /*******************************************************************
478 show a smb message structure
479 ********************************************************************/
490 ("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
491 smb_len (buf
), (int) CVAL (buf
, smb_com
), (int) CVAL (buf
, smb_rcls
), (int) CVAL (buf
,
493 (int) SVAL (buf
, smb_err
), (int) CVAL (buf
, smb_flg
), (int) SVAL (buf
, smb_flg2
)));
495 ("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
496 (int) SVAL (buf
, smb_tid
), (int) SVAL (buf
, smb_pid
), (int) SVAL (buf
, smb_uid
),
497 (int) SVAL (buf
, smb_mid
), (int) CVAL (buf
, smb_wct
)));
499 for (i
= 0; i
< (int) CVAL (buf
, smb_wct
); i
++)
501 DEBUG (5, ("smb_vwv[%d]=%d (0x%X)\n", i
,
502 SVAL (buf
, smb_vwv
+ 2 * i
), SVAL (buf
, smb_vwv
+ 2 * i
)));
505 bcc
= (int) SVAL (buf
, smb_vwv
+ 2 * (CVAL (buf
, smb_wct
)));
507 DEBUG (5, ("smb_bcc=%d\n", bcc
));
514 bcc
= MIN (bcc
, 512);
517 dump_data (10, smb_buf (buf
), bcc
);
520 /*******************************************************************
521 return the length of an smb packet
522 ********************************************************************/
526 return (PVAL (buf
, 3) | (PVAL (buf
, 2) << 8) | ((PVAL (buf
, 1) & 1) << 16));
529 /*******************************************************************
530 set the length of an smb packet
531 ********************************************************************/
533 _smb_setlen (char *buf
, int len
)
536 buf
[1] = (len
& 0x10000) >> 16;
537 buf
[2] = (len
& 0xFF00) >> 8;
541 /*******************************************************************
542 set the length and marker of an smb packet
543 ********************************************************************/
545 smb_setlen (char *buf
, int len
)
547 _smb_setlen (buf
, len
);
549 CVAL (buf
, 4) = 0xFF;
555 /*******************************************************************
556 setup the word count and byte count for a smb message
557 ********************************************************************/
559 set_message (char *buf
, int num_words
, int num_bytes
, BOOL zero
)
562 memset (buf
+ smb_size
, '\0', num_words
* 2 + num_bytes
);
563 CVAL (buf
, smb_wct
) = num_words
;
564 SSVAL (buf
, smb_vwv
+ num_words
* SIZEOFWORD
, num_bytes
);
565 smb_setlen (buf
, smb_size
+ num_words
* 2 + num_bytes
- 4);
566 return (smb_size
+ num_words
* 2 + num_bytes
);
569 /*******************************************************************
570 return the number of smb words
571 ********************************************************************/
573 smb_numwords (char *buf
)
575 return (CVAL (buf
, smb_wct
));
578 /*******************************************************************
579 return the size of the smb_buf region of a message
580 ********************************************************************/
582 smb_buflen (char *buf
)
584 return (SVAL (buf
, smb_vwv0
+ smb_numwords (buf
) * 2));
587 /*******************************************************************
588 return a pointer to the smb_buf data area
589 ********************************************************************/
591 smb_buf_ofs (char *buf
)
593 return (smb_size
+ CVAL (buf
, smb_wct
) * 2);
596 /*******************************************************************
597 return a pointer to the smb_buf data area
598 ********************************************************************/
602 return (buf
+ smb_buf_ofs (buf
));
605 /*******************************************************************
606 return the SMB offset into an SMB buffer
607 ********************************************************************/
609 smb_offset (char *p
, char *buf
)
611 return (PTR_DIFF (p
, buf
+ 4) + chain_size
);
615 /*******************************************************************
616 reduce a file name, removing .. elements.
617 ********************************************************************/
619 dos_clean_name (char *s
)
623 DEBUG (3, ("dos_clean_name [%s]\n", s
));
625 /* remove any double slashes */
626 string_sub (s
, "\\\\", "\\");
628 while ((p
= strstr (s
, "\\..\\")) != NULL
)
635 if ((p
= strrchr (s
, '\\')) != NULL
)
642 trim_string (s
, NULL
, "\\..");
644 string_sub (s
, "\\.\\", "\\");
647 /*******************************************************************
648 reduce a file name, removing .. elements.
649 ********************************************************************/
651 unix_clean_name (char *s
)
655 DEBUG (3, ("unix_clean_name [%s]\n", s
));
657 /* remove any double slashes */
658 string_sub (s
, "//", "/");
660 /* Remove leading ./ characters */
661 if (strncmp (s
, "./", 2) == 0)
663 trim_string (s
, "./", NULL
);
668 while ((p
= strstr (s
, "/../")) != NULL
)
675 if ((p
= strrchr (s
, '/')) != NULL
)
682 trim_string (s
, NULL
, "/..");
685 /*******************************************************************
686 reduce a file name, removing .. elements and checking that
687 it is below dir in the heirachy. This uses dos_GetWd() and so must be run
688 on the system that has the referenced file system.
690 widelinks are allowed if widelinks is true
691 ********************************************************************/
693 reduce_name (char *s
, char *dir
, BOOL widelinks
)
703 BOOL relative
= (*s
!= '/');
705 *dir2
= *wd
= *base_name
= *newname
= 0;
710 /* can't have a leading .. */
711 if (strncmp (s
, "..", 2) == 0 && (s
[2] == 0 || s
[2] == '/'))
713 DEBUG (3, ("Illegal file name? (%s)\n", s
));
723 DEBUG (3, ("reduce_name [%s] [%s]\n", s
, dir
));
725 /* remove any double slashes */
726 string_sub (s
, "//", "/");
728 pstrcpy (base_name
, s
);
729 p
= strrchr (base_name
, '/');
736 DEBUG (0, ("couldn't getwd for %s %s\n", s
, dir
));
740 if (dos_ChDir (dir
) != 0)
742 DEBUG (0, ("couldn't chdir to %s\n", dir
));
746 if (!dos_GetWd (dir2
))
748 DEBUG (0, ("couldn't getwd for %s\n", dir
));
753 if (p
&& (p
!= base_name
))
756 if (strcmp (p
+ 1, ".") == 0)
758 if (strcmp (p
+ 1, "..") == 0)
762 if (dos_ChDir (base_name
) != 0)
765 DEBUG (3, ("couldn't chdir for %s %s basename=%s\n", s
, dir
, base_name
));
769 if (!dos_GetWd (newname
))
772 DEBUG (2, ("couldn't get wd for %s %s\n", s
, dir2
));
776 if (p
&& (p
!= base_name
))
778 pstrcat (newname
, "/");
779 pstrcat (newname
, p
+ 1);
783 size_t l
= strlen (dir2
);
784 if (dir2
[l
- 1] == '/')
787 if (strncmp (newname
, dir2
, l
) != 0)
791 ("Bad access attempt? s=%s dir=%s newname=%s l=%d\n", s
, dir2
, newname
,
798 if (newname
[l
] == '/')
799 pstrcpy (s
, newname
+ l
+ 1);
801 pstrcpy (s
, newname
+ l
);
804 pstrcpy (s
, newname
);
812 DEBUG (3, ("reduced to %s\n", s
));
818 /****************************************************************************
820 ****************************************************************************/
822 expand_one (char *Mask
, int len
)
825 while ((p1
= strchr (Mask
, '*')) != NULL
)
827 int lfill
= (len
+ 1) - strlen (Mask
);
828 int l1
= (p1
- Mask
);
831 memset (tmp
+ l1
, '?', lfill
);
832 pstrcpy (tmp
+ l1
+ lfill
, Mask
+ l1
+ 1);
837 /****************************************************************************
838 parse out a directory name from a path name. Assumes dos style filenames.
839 ****************************************************************************/
841 dirname_dos (char *path
, char *buf
)
843 split_at_last_component (path
, buf
, '\\', NULL
);
847 /****************************************************************************
848 parse out a filename from a path name. Assumes dos style filenames.
849 ****************************************************************************/
851 filename_dos (char *path
, char *buf
)
853 char *p
= strrchr (path
, '\\');
858 pstrcpy (buf
, p
+ 1);
863 /****************************************************************************
864 expand a wildcard expression, replacing *s with ?s
865 ****************************************************************************/
867 expand_mask (char *Mask
, BOOL doext
)
874 BOOL absolute
= (*Mask
== '\\');
876 *mbeg
= *mext
= *dirpart
= *filepart
= 0;
878 /* parse the directory and filename */
879 if (strchr (Mask
, '\\'))
880 dirname_dos (Mask
, dirpart
);
882 filename_dos (Mask
, filepart
);
884 pstrcpy (mbeg
, filepart
);
885 if ((p1
= strchr (mbeg
, '.')) != NULL
)
895 if (strlen (mbeg
) > 8)
897 pstrcpy (mext
, mbeg
+ 8);
903 pstrcpy (mbeg
, "????????");
904 if ((*mext
== 0) && doext
&& !hasdot
)
905 pstrcpy (mext
, "???");
907 if (strequal (mbeg
, "*") && *mext
== 0)
911 expand_one (mbeg
, 8);
913 expand_one (mext
, 3);
915 pstrcpy (Mask
, dirpart
);
916 if (*dirpart
|| absolute
)
917 pstrcat (Mask
, "\\");
918 pstrcat (Mask
, mbeg
);
920 pstrcat (Mask
, mext
);
922 DEBUG (6, ("Mask expanded to [%s]\n", Mask
));
926 /****************************************************************************
928 ****************************************************************************/
930 make_dir_struct (char *buf
, char *mask
, char *fname
, SMB_OFF_T size
, int mode
, time_t date
)
935 pstrcpy (mask2
, mask
);
937 if ((mode
& aDIR
) != 0)
940 memset (buf
+ 1, ' ', 11);
941 if ((p
= strchr (mask2
, '.')) != NULL
)
944 memcpy (buf
+ 1, mask2
, MIN (strlen (mask2
), 8));
945 memcpy (buf
+ 9, p
+ 1, MIN (strlen (p
+ 1), 3));
949 memcpy (buf
+ 1, mask2
, MIN (strlen (mask2
), 11));
951 memset (buf
+ 21, '\0', DIR_STRUCT_SIZE
- 21);
952 CVAL (buf
, 21) = mode
;
953 put_dos_date (buf
, 22, date
);
954 SSVAL (buf
, 26, size
& 0xFFFF);
955 SSVAL (buf
, 28, (size
>> 16) & 0xFFFF);
956 StrnCpy (buf
+ 30, fname
, 12);
959 DEBUG (8, ("put name [%s] into dir struct\n", buf
+ 30));
963 /*******************************************************************
964 close the low 3 fd's and open dev/null in their place
965 ********************************************************************/
974 /* try and use up these file descriptors, so silly
975 library routines writing to stdout etc won't cause havoc */
976 for (i
= 0; i
< 3; i
++)
978 fd
= sys_open ("/dev/null", O_RDWR
, 0);
980 fd
= sys_open ("/dev/null", O_WRONLY
, 0);
983 DEBUG (0, ("Cannot open /dev/null\n"));
988 DEBUG (0, ("Didn't get file descriptor %d\n", i
));
995 /****************************************************************************
996 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1000 ****************************************************************************/
1002 set_blocking (int fd
, BOOL set
)
1006 #define FLAG_TO_SET O_NONBLOCK
1009 #define FLAG_TO_SET O_NDELAY
1011 #define FLAG_TO_SET FNDELAY
1015 if ((val
= fcntl (fd
, F_GETFL
, 0)) == -1)
1017 if (set
) /* Turn blocking on - ie. clear nonblock flag */
1018 val
&= ~FLAG_TO_SET
;
1021 return fcntl (fd
, F_SETFL
, val
);
1026 /*******************************************************************
1027 find the difference in milliseconds between two struct timeval
1029 ********************************************************************/
1031 TvalDiff (struct timeval
*tvalold
, struct timeval
*tvalnew
)
1033 return ((tvalnew
->tv_sec
- tvalold
->tv_sec
) * 1000 +
1034 ((int) tvalnew
->tv_usec
- (int) tvalold
->tv_usec
) / 1000);
1039 /****************************************************************************
1040 transfer some data between two fd's
1041 ****************************************************************************/
1043 transfer_file (int infd
, int outfd
, SMB_OFF_T n
, char *header
, int headlen
, int align
)
1045 static char *buf
= NULL
;
1046 static int size
= 0;
1048 SMB_OFF_T total
= 0;
1050 DEBUG (4, ("transfer_file n=%.0f (head=%d) called\n", (double) n
, headlen
));
1054 size
= lp_readsize ();
1055 size
= MAX (size
, 1024);
1058 while (!buf
&& size
> 0)
1060 buf
= (char *) Realloc (buf
, size
+ 8);
1067 DEBUG (0, ("Cannot allocate transfer buffer!\n"));
1071 abuf
= buf
+ (align
% 8);
1078 int s
= (int) MIN (n
, (SMB_OFF_T
) size
);
1083 if (header
&& (headlen
>= MIN (s
, 1024)))
1096 if (header
&& headlen
> 0)
1098 ret
= MIN (headlen
, size
);
1099 memcpy (buf1
, header
, ret
);
1107 ret
+= read (infd
, buf1
+ ret
, s
- ret
);
1111 ret2
= (outfd
>= 0 ? write_data (outfd
, buf1
, ret
) : ret
);
1114 /* if we can't write then dump excess data */
1116 transfer_file (infd
, -1, n
- (ret
+ headlen
), NULL
, 0, 0);
1118 if (ret
<= 0 || ret2
!= ret
)
1126 /****************************************************************************
1127 find a pointer to a netbios name
1128 ****************************************************************************/
1130 name_ptr (char *buf
, int ofs
)
1132 unsigned char c
= *(unsigned char *) (buf
+ ofs
);
1134 if ((c
& 0xC0) == 0xC0)
1138 memcpy (p
, buf
+ ofs
, 2);
1141 DEBUG (5, ("name ptr to pos %d from %d is %s\n", l
, ofs
, buf
+ l
));
1148 /****************************************************************************
1149 extract a netbios name from a buf
1150 ****************************************************************************/
1152 name_extract (char *buf
, int ofs
, char *name
)
1154 char *p
= name_ptr (buf
, ofs
);
1155 int d
= PTR_DIFF (p
, buf
+ ofs
);
1157 if (d
< -50 || d
> 50)
1159 return (name_interpret (p
, name
));
1163 /****************************************************************************
1164 return the total storage length of a mangled name
1165 ****************************************************************************/
1169 /* NOTE: this argument _must_ be unsigned */
1170 unsigned char *s
= (unsigned char *) s1
;
1173 /* If the two high bits of the byte are set, return 2. */
1174 if (0xC0 == (*s
& 0xC0))
1177 /* Add up the length bytes. */
1178 for (len
= 1; (*s
); s
+= (*s
) + 1)
1181 SMB_ASSERT (len
< 80);
1188 /*******************************************************************
1189 sleep for a specified number of milliseconds
1190 ********************************************************************/
1195 struct timeval tval
, t1
, t2
;
1203 tval
.tv_sec
= (t
- tdiff
) / 1000;
1204 tval
.tv_usec
= 1000 * ((t
- tdiff
) % 1000);
1208 sys_select (0, &fds
, &tval
);
1211 tdiff
= TvalDiff (&t1
, &t2
);
1216 /*********************************************************
1217 * Recursive routine that is called by unix_mask_match.
1218 * Does the actual matching. This is the 'original code'
1219 * used by the unix matcher.
1220 *********************************************************/
1222 unix_do_match (char *str
, char *regexp
, int case_sig
)
1226 for (p
= regexp
; *p
&& *str
;)
1236 /* Look for a character matching
1237 the one after the '*' */
1240 return True
; /* Automatic match */
1243 while (*str
&& (case_sig
? (*p
!= *str
) : (toupper (*p
) != toupper (*str
))))
1245 if (unix_do_match (str
, p
, case_sig
))
1262 if (toupper (*str
) != toupper (*p
))
1272 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1275 if (!*str
&& *p
== '?')
1282 if (!*str
&& (*p
== '*' && p
[1] == '\0'))
1288 /*********************************************************
1289 * Routine to match a given string with a regexp - uses
1290 * simplified regexp that takes * and ? only. Case can be
1291 * significant or not.
1292 * This is the 'original code' used by the unix matcher.
1293 *********************************************************/
1296 unix_mask_match (char *str
, char *regexp
, int case_sig
, BOOL trans2
)
1300 fstring ebase
, eext
, sbase
, sext
;
1304 /* Make local copies of str and regexp */
1305 StrnCpy (p1
, regexp
, sizeof (pstring
) - 1);
1306 StrnCpy (p2
, str
, sizeof (pstring
) - 1);
1308 if (!strchr (p2
, '.'))
1313 /* Remove any *? and ** as they are meaningless */
1314 for (p
= p1
; *p
; p
++)
1315 while (*p
== '*' && (p
[1] == '?' || p
[1] == '*'))
1316 (void) pstrcpy (&p
[1], &p
[2]);
1318 if (strequal (p1
, "*"))
1321 DEBUG (8, ("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
1325 fstrcpy (ebase
, p1
);
1326 fstrcpy (sbase
, p2
);
1330 if ((p
= strrchr (p1
, '.')))
1333 fstrcpy (ebase
, p1
);
1334 fstrcpy (eext
, p
+ 1);
1338 fstrcpy (ebase
, p1
);
1342 if (!strequal (p2
, ".") && !strequal (p2
, "..") && (p
= strrchr (p2
, '.')))
1345 fstrcpy (sbase
, p2
);
1346 fstrcpy (sext
, p
+ 1);
1350 fstrcpy (sbase
, p2
);
1355 matched
= unix_do_match (sbase
, ebase
, case_sig
) &&
1356 (trans2
|| unix_do_match (sext
, eext
, case_sig
));
1358 DEBUG (8, ("unix_mask_match returning %d\n", matched
));
1363 /*********************************************************
1364 * Recursive routine that is called by mask_match.
1365 * Does the actual matching. Returns True if matched,
1366 * False if failed. This is the 'new' NT style matcher.
1367 *********************************************************/
1370 do_match (char *str
, char *regexp
, int case_sig
)
1374 for (p
= regexp
; *p
&& *str
;)
1384 /* Look for a character matching
1385 the one after the '*' */
1388 return True
; /* Automatic match */
1391 while (*str
&& (case_sig
? (*p
!= *str
) : (toupper (*p
) != toupper (*str
))))
1393 /* Now eat all characters that match, as
1394 we want the *last* character to match. */
1395 while (*str
&& (case_sig
? (*p
== *str
) : (toupper (*p
) == toupper (*str
))))
1397 str
--; /* We've eaten the match char after the '*' */
1398 if (do_match (str
, p
, case_sig
))
1423 if (toupper (*str
) != toupper (*p
))
1436 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1441 if (!*str
&& *p
== '?')
1448 if (!*str
&& (*p
== '*' && p
[1] == '\0'))
1457 /*********************************************************
1458 * Routine to match a given string with a regexp - uses
1459 * simplified regexp that takes * and ? only. Case can be
1460 * significant or not.
1461 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
1462 * This is the new 'NT style' matcher.
1463 *********************************************************/
1466 mask_match (char *str
, char *regexp
, int case_sig
, BOOL trans2
)
1469 pstring t_pattern
, t_filename
, te_pattern
, te_filename
;
1470 fstring ebase
, eext
, sbase
, sext
;
1472 BOOL matched
= False
;
1474 /* Make local copies of str and regexp */
1475 pstrcpy (t_pattern
, regexp
);
1476 pstrcpy (t_filename
, str
);
1481 /* a special case for 16 bit apps */
1482 if (strequal (t_pattern
, "????????.???"))
1483 pstrcpy (t_pattern
, "*");
1487 * Handle broken clients that send us old 8.3 format.
1489 string_sub (t_pattern
, "????????", "*");
1490 string_sub (t_pattern
, ".???", ".*");
1496 * Not sure if this is a good idea. JRA.
1498 if (trans2
&& is_8_3 (t_pattern
, False
) && is_8_3 (t_filename
, False
))
1503 if (!strchr (t_filename
, '.'))
1505 pstrcat (t_filename
, ".");
1509 /* Remove any *? and ** as they are meaningless */
1510 string_sub (t_pattern
, "*?", "*");
1511 string_sub (t_pattern
, "**", "*");
1513 if (strequal (t_pattern
, "*"))
1517 ("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename
, t_pattern
, case_sig
));
1522 * Match each component of the regexp, split up by '.'
1525 char *fp
, *rp
, *cp2
, *cp1
;
1526 BOOL last_wcard_was_star
= False
;
1527 int num_path_components
, num_regexp_components
;
1529 pstrcpy (te_pattern
, t_pattern
);
1530 pstrcpy (te_filename
, t_filename
);
1532 * Remove multiple "*." patterns.
1534 string_sub (te_pattern
, "*.*.", "*.");
1535 num_regexp_components
= count_chars (te_pattern
, '.');
1536 num_path_components
= count_chars (te_filename
, '.');
1539 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
1541 if (num_regexp_components
== 0)
1542 matched
= do_match (te_filename
, te_pattern
, case_sig
);
1545 for (cp1
= te_pattern
, cp2
= te_filename
; cp1
;)
1547 fp
= strchr (cp2
, '.');
1550 rp
= strchr (cp1
, '.');
1554 if (cp1
[strlen (cp1
) - 1] == '*')
1555 last_wcard_was_star
= True
;
1557 last_wcard_was_star
= False
;
1559 if (!do_match (cp2
, cp1
, case_sig
))
1562 cp1
= rp
? rp
+ 1 : NULL
;
1563 cp2
= fp
? fp
+ 1 : "";
1565 if (last_wcard_was_star
|| ((cp1
!= NULL
) && (*cp1
== '*')))
1567 /* Eat the extra path components. */
1570 for (i
= 0; i
< num_path_components
- num_regexp_components
; i
++)
1572 fp
= strchr (cp2
, '.');
1576 if ((cp1
!= NULL
) && do_match (cp2
, cp1
, case_sig
))
1578 cp2
= fp
? fp
+ 1 : "";
1581 cp2
= fp
? fp
+ 1 : "";
1583 num_path_components
-= i
;
1586 if (cp1
== NULL
&& ((*cp2
== '\0') || last_wcard_was_star
))
1593 /* -------------------------------------------------
1594 * Behaviour of Win95
1595 * for 8.3 filenames and 8.3 Wildcards
1596 * -------------------------------------------------
1598 if (strequal (t_filename
, "."))
1601 * Patterns: *.* *. ?. ? ????????.??? are valid.
1604 if (strequal (t_pattern
, "*.*") || strequal (t_pattern
, "*.") ||
1605 strequal (t_pattern
, "????????.???") ||
1606 strequal (t_pattern
, "?.") || strequal (t_pattern
, "?"))
1609 else if (strequal (t_filename
, ".."))
1612 * Patterns: *.* *. ?. ? *.? ????????.??? are valid.
1615 if (strequal (t_pattern
, "*.*") || strequal (t_pattern
, "*.") ||
1616 strequal (t_pattern
, "?.") || strequal (t_pattern
, "?") ||
1617 strequal (t_pattern
, "????????.???") ||
1618 strequal (t_pattern
, "*.?") || strequal (t_pattern
, "?.*"))
1624 if ((p
= strrchr (t_pattern
, '.')))
1627 * Wildcard has a suffix.
1630 fstrcpy (ebase
, t_pattern
);
1633 fstrcpy (eext
, p
+ 1);
1637 /* pattern ends in DOT: treat as if there is no DOT */
1639 if (strequal (ebase
, "*"))
1646 * No suffix for wildcard.
1648 fstrcpy (ebase
, t_pattern
);
1652 p
= strrchr (t_filename
, '.');
1653 if (p
&& (p
[1] == 0))
1656 * Filename has an extension of '.' only.
1658 *p
= 0; /* nuke dot at end of string */
1659 p
= 0; /* and treat it as if there is no extension */
1665 * Filename has an extension.
1668 fstrcpy (sbase
, t_filename
);
1669 fstrcpy (sext
, p
+ 1);
1672 matched
= do_match (sbase
, ebase
, case_sig
) && do_match (sext
, eext
, case_sig
);
1676 /* pattern has no extension */
1677 /* Really: match complete filename with pattern ??? means exactly 3 chars */
1678 matched
= do_match (str
, ebase
, case_sig
);
1684 * Filename has no extension.
1686 fstrcpy (sbase
, t_filename
);
1690 /* pattern has extension */
1691 matched
= do_match (sbase
, ebase
, case_sig
) && do_match (sext
, eext
, case_sig
);
1695 matched
= do_match (sbase
, ebase
, case_sig
);
1696 #ifdef EMULATE_WEIRD_W95_MATCHING
1698 * Even Microsoft has some problems
1699 * Behaviour Win95 -> local disk
1700 * is different from Win95 -> smb drive from Nt 4.0
1701 * This branch would reflect the Win95 local disk behaviour
1705 /* a? matches aa and a in w95 */
1706 fstrcat (sbase
, ".");
1707 matched
= do_match (sbase
, ebase
, case_sig
);
1715 DEBUG (8, ("mask_match returning %d\n", matched
));
1722 /****************************************************************************
1723 set the length of a file from a filedescriptor.
1724 Returns 0 on success, -1 on failure.
1725 ****************************************************************************/
1728 set_filelen (int fd
, SMB_OFF_T len
)
1730 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1731 extend a file with ftruncate. Provide alternate implementation
1734 #ifdef HAVE_FTRUNCATE_EXTEND
1735 return sys_ftruncate (fd
, len
);
1739 SMB_OFF_T currpos
= sys_lseek (fd
, (SMB_OFF_T
) 0, SEEK_CUR
);
1743 /* Do an fstat to see if the file is longer than
1744 the requested size (call ftruncate),
1745 or shorter, in which case seek to len - 1 and write 1
1747 if (sys_fstat (fd
, &st
) < 0)
1751 if (S_ISFIFO (st
.st_mode
))
1755 if (st
.st_size
== len
)
1757 if (st
.st_size
> len
)
1758 return sys_ftruncate (fd
, len
);
1760 if (sys_lseek (fd
, len
- 1, SEEK_SET
) != len
- 1)
1762 if (write (fd
, &c
, 1) != 1)
1764 /* Seek to where we were */
1765 if (sys_lseek (fd
, currpos
, SEEK_SET
) != currpos
)
1773 /****************************************************************************
1774 this is a version of setbuffer() for those machines that only have setvbuf
1775 ****************************************************************************/
1777 setbuffer (FILE * f
, char *buf
, int bufsize
)
1779 setvbuf (f
, buf
, _IOFBF
, bufsize
);
1786 /****************************************************************************
1787 expand a pointer to be a particular size
1788 ****************************************************************************/
1790 Realloc (void *p
, size_t size
)
1798 DEBUG (5, ("Realloc asked for 0 bytes\n"));
1803 ret
= (void *) malloc (size
);
1805 ret
= (void *) realloc (p
, size
);
1810 smb_mem_write_info (ret
, dbf
);
1815 DEBUG (0, ("Memory allocation error: failed to expand to %d bytes\n", (int) size
));
1821 /****************************************************************************
1822 get my own name and IP
1823 ****************************************************************************/
1825 get_myname (char *my_name
, struct in_addr
* ip
)
1830 /* cppcheck-suppress uninitvar */
1833 /* get my host name */
1834 if (gethostname (hostname
, sizeof (hostname
)) == -1)
1836 DEBUG (0, ("gethostname failed\n"));
1840 /* Ensure null termination. */
1841 hostname
[sizeof (hostname
) - 1] = '\0';
1844 if ((hp
= Get_Hostbyname (hostname
)) == 0)
1846 DEBUG (0, ("Get_Hostbyname: Unknown host %s\n", hostname
));
1852 /* split off any parts after an initial . */
1853 char *p
= strchr (hostname
, '.');
1857 fstrcpy (my_name
, hostname
);
1861 putip ((char *) ip
, (char *) hp
->h_addr
);
1867 /****************************************************************************
1868 true if two IP addresses are equal
1869 ****************************************************************************/
1871 ip_equal (struct in_addr ip1
, struct in_addr ip2
)
1874 a1
= ntohl (ip1
.s_addr
);
1875 a2
= ntohl (ip2
.s_addr
);
1879 #if 0 /* May be useful one day */
1880 /****************************************************************************
1881 interpret a protocol description string, with a default
1882 ****************************************************************************/
1884 interpret_protocol (char *str
, int def
)
1886 if (strequal (str
, "NT1"))
1887 return (PROTOCOL_NT1
);
1888 if (strequal (str
, "LANMAN2"))
1889 return (PROTOCOL_LANMAN2
);
1890 if (strequal (str
, "LANMAN1"))
1891 return (PROTOCOL_LANMAN1
);
1892 if (strequal (str
, "CORE"))
1893 return (PROTOCOL_CORE
);
1894 if (strequal (str
, "COREPLUS"))
1895 return (PROTOCOL_COREPLUS
);
1896 if (strequal (str
, "CORE+"))
1897 return (PROTOCOL_COREPLUS
);
1899 DEBUG (0, ("Unrecognised protocol level %s\n", str
));
1905 /****************************************************************************
1906 interpret an internet address or name into an IP address in 4 byte form
1907 ****************************************************************************/
1909 interpret_addr (const char *str
)
1914 BOOL pure_address
= True
;
1916 if (strcmp (str
, "0.0.0.0") == 0)
1918 if (strcmp (str
, "255.255.255.255") == 0)
1919 return (0xFFFFFFFF);
1921 for (i
= 0; pure_address
&& str
[i
]; i
++)
1922 if (!(isdigit ((int) str
[i
]) || str
[i
] == '.'))
1923 pure_address
= False
;
1925 /* if it's in the form of an IP address then get the lib to interpret it */
1928 res
= inet_addr (str
);
1932 /* otherwise assume it's a network name of some sort and use
1934 if ((hp
= Get_Hostbyname (str
)) == 0)
1936 DEBUG (3, ("Get_Hostbyname: Unknown host. %s\n", str
));
1939 if (hp
->h_addr
== NULL
)
1941 DEBUG (3, ("Get_Hostbyname: host address is invalid for host %s\n", str
));
1944 putip ((char *) &res
, (char *) hp
->h_addr
);
1947 if (res
== (uint32
) - 1)
1953 /*******************************************************************
1954 a convenient addition to interpret_addr()
1955 ******************************************************************/
1957 interpret_addr2 (const char *str
)
1959 static struct in_addr ret
;
1960 uint32 a
= interpret_addr (str
);
1965 /*******************************************************************
1966 check if an IP is the 0.0.0.0
1967 ******************************************************************/
1969 zero_ip (struct in_addr ip
)
1972 putip ((char *) &a
, (char *) &ip
);
1977 /*******************************************************************
1978 matchname - determine if host name matches IP address
1979 ******************************************************************/
1981 matchname (char *remotehost
, struct in_addr addr
)
1986 if ((hp
= Get_Hostbyname (remotehost
)) == 0)
1988 DEBUG (0, ("Get_Hostbyname(%s): lookup failure.\n", remotehost
));
1993 * Make sure that gethostbyname() returns the "correct" host name.
1994 * Unfortunately, gethostbyname("localhost") sometimes yields
1995 * "localhost.domain". Since the latter host name comes from the
1996 * local DNS, we just have to trust it (all bets are off if the local
1997 * DNS is perverted). We always check the address list, though.
2000 if (strcasecmp (remotehost
, hp
->h_name
) && strcasecmp (remotehost
, "localhost"))
2002 DEBUG (0, ("host name/name mismatch: %s != %s\n", remotehost
, hp
->h_name
));
2006 /* Look up the host address in the address list we just got. */
2007 for (i
= 0; hp
->h_addr_list
[i
]; i
++)
2009 if (memcmp (hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof (addr
)) == 0)
2014 * The host name does not map to the original host address. Perhaps
2015 * someone has compromised a name server. More likely someone botched
2016 * it, but that could be dangerous, too.
2019 DEBUG (0, ("host name/address mismatch: %s != %s\n", inet_ntoa (addr
), hp
->h_name
));
2024 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
2025 /******************************************************************
2026 Remove any mount options such as -rsize=2048,wsize=2048 etc.
2027 Based on a fix from <Thomas.Hepper@icem.de>.
2028 *******************************************************************/
2031 strip_mount_options (pstring
* str
)
2036 while (*p
&& !isspace (*p
))
2038 while (*p
&& isspace (*p
))
2044 pstrcpy (tmp_str
, p
);
2045 pstrcpy (*str
, tmp_str
);
2050 /*******************************************************************
2051 Patch from jkf@soton.ac.uk
2052 Split Luke's automount_server into YP lookup and string splitter
2053 so can easily implement automount_path().
2054 As we may end up doing both, cache the last YP result.
2055 *******************************************************************/
2057 #ifdef WITH_NISPLUS_HOME
2059 automount_lookup (char *user_name
)
2061 static fstring last_key
= "";
2062 static pstring last_value
= "";
2064 char *nis_map
= (char *) lp_nis_home_map_name ();
2066 char buffer
[NIS_MAXATTRVAL
+ 1];
2071 DEBUG (5, ("NIS+ Domain: %s\n", (char *) nis_local_directory ()));
2073 if (strcmp (user_name
, last_key
))
2075 slprintf (buffer
, sizeof (buffer
) - 1, "[%s=%s]%s.%s", "key", user_name
, nis_map
,
2076 (char *) nis_local_directory ());
2077 DEBUG (5, ("NIS+ querystring: %s\n", buffer
));
2079 if (result
= nis_list (buffer
, RETURN_RESULT
, NULL
, NULL
))
2081 if (result
->status
!= NIS_SUCCESS
)
2083 DEBUG (3, ("NIS+ query failed: %s\n", nis_sperrno (result
->status
)));
2084 fstrcpy (last_key
, "");
2085 pstrcpy (last_value
, "");
2089 object
= result
->objects
.objects_val
;
2090 if (object
->zo_data
.zo_type
== ENTRY_OBJ
)
2092 entry
= &object
->zo_data
.objdata_u
.en_data
;
2093 DEBUG (5, ("NIS+ entry type: %s\n", entry
->en_type
));
2095 ("NIS+ result: %s\n",
2096 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
2098 pstrcpy (last_value
, entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
2099 string_sub (last_value
, "&", user_name
);
2100 fstrcpy (last_key
, user_name
);
2104 nis_freeresult (result
);
2107 strip_mount_options (&last_value
);
2109 DEBUG (4, ("NIS+ Lookup: %s resulted in %s\n", user_name
, last_value
));
2112 #else /* WITH_NISPLUS_HOME */
2114 automount_lookup (char *user_name
)
2116 static fstring last_key
= "";
2117 static pstring last_value
= "";
2119 int nis_error
; /* returned by yp all functions */
2120 char *nis_result
; /* yp_match inits this */
2121 int nis_result_len
; /* and set this */
2122 char *nis_domain
; /* yp_get_default_domain inits this */
2123 char *nis_map
= (char *) lp_nis_home_map_name ();
2125 if ((nis_error
= yp_get_default_domain (&nis_domain
)) != 0)
2127 DEBUG (3, ("YP Error: %s\n", yperr_string (nis_error
)));
2131 DEBUG (5, ("NIS Domain: %s\n", nis_domain
));
2133 if (!strcmp (user_name
, last_key
))
2135 nis_result
= last_value
;
2136 nis_result_len
= strlen (last_value
);
2141 if ((nis_error
= yp_match (nis_domain
, nis_map
,
2142 user_name
, strlen (user_name
),
2143 &nis_result
, &nis_result_len
)) != 0)
2145 DEBUG (3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
2146 yperr_string (nis_error
), user_name
, nis_map
));
2148 if (!nis_error
&& nis_result_len
>= sizeof (pstring
))
2150 nis_result_len
= sizeof (pstring
) - 1;
2152 fstrcpy (last_key
, user_name
);
2153 strncpy (last_value
, nis_result
, nis_result_len
);
2154 last_value
[nis_result_len
] = '\0';
2157 strip_mount_options (&last_value
);
2159 DEBUG (4, ("YP Lookup: %s resulted in %s\n", user_name
, last_value
));
2162 #endif /* WITH_NISPLUS_HOME */
2165 /*******************************************************************
2166 Patch from jkf@soton.ac.uk
2167 This is Luke's original function with the NIS lookup code
2168 moved out to a separate function.
2169 *******************************************************************/
2171 automount_server (const char *user_name
)
2173 static pstring server_name
;
2176 /* use the local machine name as the default */
2177 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2178 pstrcpy (server_name
, local_machine
);
2180 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2182 if (lp_nis_home_map ())
2184 int home_server_len
;
2185 char *automount_value
= automount_lookup (user_name
);
2186 home_server_len
= strcspn (automount_value
, ":");
2187 DEBUG (5, ("NIS lookup succeeded. Home server length: %d\n", home_server_len
));
2188 if (home_server_len
> sizeof (pstring
))
2190 home_server_len
= sizeof (pstring
);
2192 strncpy (server_name
, automount_value
, home_server_len
);
2193 server_name
[home_server_len
] = '\0';
2197 DEBUG (4, ("Home server: %s\n", server_name
));
2202 /*******************************************************************
2203 Patch from jkf@soton.ac.uk
2204 Added this to implement %p (NIS auto-map version of %H)
2205 *******************************************************************/
2207 automount_path (char *user_name
)
2209 static pstring server_path
;
2211 /* use the passwd entry as the default */
2212 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2213 /* pstrcpy() copes with get_home_dir() returning NULL */
2214 pstrcpy (server_path
, get_home_dir (user_name
));
2216 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2218 if (lp_nis_home_map ())
2220 char *home_path_start
;
2221 char *automount_value
= automount_lookup (user_name
);
2222 home_path_start
= strchr (automount_value
, ':');
2223 if (home_path_start
!= NULL
)
2225 DEBUG (5, ("NIS lookup succeeded. Home path is: %s\n",
2226 home_path_start
? (home_path_start
+ 1) : ""));
2227 pstrcpy (server_path
, home_path_start
+ 1);
2232 DEBUG (4, ("Home server path: %s\n", server_path
));
2238 /*******************************************************************
2239 sub strings with useful parameters
2240 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
2241 Paul Rippin <pr3245@nopc.eurostat.cec.be>
2242 ********************************************************************/
2244 standard_sub_basic (char *str
)
2248 struct passwd
*pass
;
2249 const char *username
= sam_logon_in_ssb
? samlogon_user
: sesssetup_user
;
2251 for (s
= str
; s
&& *s
&& (p
= strchr (s
, '%')); s
= p
)
2257 if ((pass
= Get_Pwnam (username
)) != NULL
)
2259 string_sub (p
, "%G", gidtoname (pass
->pw_gid
));
2268 string_sub (p
, "%N", automount_server (username
));
2271 string_sub (p
, "%I", client_addr (Client
));
2274 string_sub (p
, "%L", local_machine
);
2277 string_sub (p
, "%M", client_name (Client
));
2280 string_sub (p
, "%R", remote_proto
);
2283 string_sub (p
, "%T", timestring ());
2286 string_sub (p
, "%U", username
);
2289 string_sub (p
, "%a", remote_arch
);
2293 slprintf (pidstr
, sizeof (pidstr
) - 1, "%d", (int) getpid ());
2294 string_sub (p
, "%d", pidstr
);
2298 string_sub (p
, "%h", myhostname
);
2301 string_sub (p
, "%m", remote_machine
);
2304 string_sub (p
, "%v", VERSION
);
2306 case '$': /* Expand environment variables */
2308 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
2314 if (*(p
+ 2) != '(')
2319 if ((q
= strchr (p
, ')')) == NULL
)
2321 DEBUG (0, ("standard_sub_basic: Unterminated environment \
2322 variable [%s]\n", p
));
2328 copylen
= MIN ((size_t) (q
- r
), (size_t) (sizeof (envname
) - 1));
2329 strncpy (envname
, r
, copylen
);
2330 envname
[copylen
] = '\0';
2332 if ((envval
= getenv (envname
)) == NULL
)
2334 DEBUG (0, ("standard_sub_basic: Environment variable [%s] not set\n", envname
));
2339 copylen
= MIN ((size_t) (q
+ 1 - p
), (size_t) (sizeof (envname
) - 1));
2340 strncpy (envname
, p
, copylen
);
2341 envname
[copylen
] = '\0';
2342 string_sub (p
, envname
, envval
);
2347 break; /* don't run off end if last character is % */
2357 /****************************************************************************
2358 do some standard substitutions in a string
2359 ****************************************************************************/
2361 standard_sub (connection_struct
* conn
, char *str
)
2366 for (s
= str
; (p
= strchr (s
, '%')); s
= p
)
2371 if ((home
= get_home_dir (conn
->user
)))
2373 string_sub (p
, "%H", home
);
2382 string_sub (p
, "%P", conn
->connectpath
);
2386 string_sub (p
, "%S", lp_servicename (SNUM (conn
)));
2390 string_sub (p
, "%g", gidtoname (conn
->gid
));
2393 string_sub (p
, "%u", conn
->user
);
2396 /* Patch from jkf@soton.ac.uk Left the %N (NIS
2397 * server name) in standard_sub_basic as it is
2398 * a feature for logon servers, hence uses the
2399 * username. The %p (NIS server path) code is
2400 * here as it is used instead of the default
2401 * "path =" string in [homes] and so needs the
2402 * service name, not the username. */
2404 string_sub (p
, "%p", automount_path (lp_servicename (SNUM (conn
))));
2408 break; /* don't run off the end of the string
2417 standard_sub_basic (str
);
2422 /*******************************************************************
2423 are two IPs on the same subnet?
2424 ********************************************************************/
2426 same_net (struct in_addr ip1
, struct in_addr ip2
, struct in_addr mask
)
2428 uint32 net1
, net2
, nmask
;
2430 nmask
= ntohl (mask
.s_addr
);
2431 net1
= ntohl (ip1
.s_addr
);
2432 net2
= ntohl (ip2
.s_addr
);
2434 return ((net1
& nmask
) == (net2
& nmask
));
2438 /****************************************************************************
2439 a wrapper for gethostbyname() that tries with all lower and all upper case
2440 if the initial name fails
2441 ****************************************************************************/
2443 Get_Hostbyname (const char *name
)
2445 char *name2
= strdup (name
);
2446 struct hostent
*ret
;
2450 DEBUG (0, ("Memory allocation error in Get_Hostbyname! panic\n"));
2456 * This next test is redundent and causes some systems (with
2457 * broken isalnum() calls) problems.
2462 if (!isalnum (*name2
))
2469 ret
= sys_gethostbyname (name2
);
2476 /* try with all lowercase */
2478 ret
= sys_gethostbyname (name2
);
2485 /* try with all uppercase */
2487 ret
= sys_gethostbyname (name2
);
2494 /* nothing works :-( */
2500 /*******************************************************************
2501 turn a uid into a user name
2502 ********************************************************************/
2504 uidtoname (uid_t uid
)
2506 static char name
[40];
2507 struct passwd
*pass
= getpwuid (uid
);
2509 return (pass
->pw_name
);
2510 slprintf (name
, sizeof (name
) - 1, "%d", (int) uid
);
2515 /*******************************************************************
2516 turn a gid into a group name
2517 ********************************************************************/
2520 gidtoname (gid_t gid
)
2522 static char name
[40];
2523 struct group
*grp
= getgrgid (gid
);
2525 return (grp
->gr_name
);
2526 slprintf (name
, sizeof (name
) - 1, "%d", (int) gid
);
2531 /*******************************************************************
2532 turn a user name into a uid
2533 ********************************************************************/
2535 nametouid (const char *name
)
2537 struct passwd
*pass
= getpwnam (name
);
2539 return (pass
->pw_uid
);
2543 /*******************************************************************
2544 something really nasty happened - panic!
2545 ********************************************************************/
2547 smb_panic (const char *why
)
2549 const char *cmd
= lp_panic_action ();
2554 DEBUG (0, ("PANIC: cannot run panic handler command \"%s\"\n", cmd
));
2557 DEBUG (0, ("PANIC: %s\n", why
));
2563 /*******************************************************************
2564 a readdir wrapper which just returns the file name
2565 ********************************************************************/
2567 readdirname (DIR * p
)
2569 SMB_STRUCT_DIRENT
*ptr
;
2575 ptr
= (SMB_STRUCT_DIRENT
*) sys_readdir (p
);
2579 dname
= ptr
->d_name
;
2582 if (telldir (p
) < 0)
2586 #ifdef HAVE_BROKEN_READDIR
2587 /* using /usr/ucb/cc is BAD */
2593 memcpy (buf
, dname
, NAMLEN (ptr
) + 1);
2600 /*******************************************************************
2601 Utility function used to decide if the last component
2602 of a path matches a (possibly wildcarded) entry in a namelist.
2603 ********************************************************************/
2606 is_in_path (char *name
, name_compare_entry
* namelist
)
2608 pstring last_component
;
2611 DEBUG (8, ("is_in_path: %s\n", name
));
2613 /* if we have no list it's obviously not in the path */
2614 if ((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
)))
2616 DEBUG (8, ("is_in_path: no name list.\n"));
2620 /* Get the last component of the unix name. */
2621 p
= strrchr (name
, '/');
2622 strncpy (last_component
, p
? ++p
: name
, sizeof (last_component
) - 1);
2623 last_component
[sizeof (last_component
) - 1] = '\0';
2625 for (; namelist
->name
!= NULL
; namelist
++)
2627 if (namelist
->is_wild
)
2630 * Look for a wildcard match. Use the old
2631 * 'unix style' mask match, rather than the
2634 if (unix_mask_match (last_component
, namelist
->name
, case_sensitive
, False
))
2636 DEBUG (8, ("is_in_path: mask match succeeded\n"));
2642 if ((case_sensitive
&& (strcmp (last_component
, namelist
->name
) == 0)) ||
2643 (!case_sensitive
&& (StrCaseCmp (last_component
, namelist
->name
) == 0)))
2645 DEBUG (8, ("is_in_path: match succeeded\n"));
2650 DEBUG (8, ("is_in_path: match not found\n"));
2655 /*******************************************************************
2656 Strip a '/' separated list into an array of
2657 name_compare_enties structures suitable for
2658 passing to is_in_path(). We do this for
2659 speed so we can pre-parse all the names in the list
2660 and don't do it for each call to is_in_path().
2661 namelist is modified here and is assumed to be
2662 a copy owned by the caller.
2663 We also check if the entry contains a wildcard to
2664 remove a potentially expensive call to mask_match
2666 ********************************************************************/
2669 set_namearray (name_compare_entry
** ppname_array
, char *namelist
)
2672 char *nameptr
= namelist
;
2673 int num_entries
= 0;
2676 (*ppname_array
) = NULL
;
2678 if ((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
2681 /* We need to make two passes over the string. The
2682 first to count the number of elements, the second
2687 if (*nameptr
== '/')
2689 /* cope with multiple (useless) /s) */
2693 /* find the next / */
2694 name_end
= strchr (nameptr
, '/');
2696 /* oops - the last check for a / didn't find one. */
2697 if (name_end
== NULL
)
2700 /* next segment please */
2701 nameptr
= name_end
+ 1;
2705 if (num_entries
== 0)
2708 if (((*ppname_array
) = (name_compare_entry
*) malloc ((num_entries
+
2709 1) * sizeof (name_compare_entry
))) ==
2712 DEBUG (0, ("set_namearray: malloc fail\n"));
2716 /* Now copy out the names */
2721 if (*nameptr
== '/')
2723 /* cope with multiple (useless) /s) */
2727 /* find the next / */
2728 if ((name_end
= strchr (nameptr
, '/')) != NULL
)
2733 /* oops - the last check for a / didn't find one. */
2734 if (name_end
== NULL
)
2737 (*ppname_array
)[i
].is_wild
= ((strchr (nameptr
, '?') != NULL
) ||
2738 (strchr (nameptr
, '*') != NULL
));
2739 if (((*ppname_array
)[i
].name
= strdup (nameptr
)) == NULL
)
2741 DEBUG (0, ("set_namearray: malloc fail (1)\n"));
2745 /* next segment please */
2746 nameptr
= name_end
+ 1;
2750 (*ppname_array
)[i
].name
= NULL
;
2755 /****************************************************************************
2756 routine to free a namearray.
2757 ****************************************************************************/
2760 free_namearray (name_compare_entry
* name_array
)
2762 if (name_array
== 0)
2765 if (name_array
->name
!= NULL
)
2766 free (name_array
->name
);
2768 free ((char *) name_array
);
2772 /*******************************************************************
2773 is the name specified one of my netbios names
2774 returns true is it is equal, false otherwise
2775 ********************************************************************/
2782 for (n
= 0; my_netbios_names
[n
]; n
++)
2784 if (strequal (my_netbios_names
[n
], s
))
2787 DEBUG (8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
2791 #if 0 /* Can be useful one day */
2792 /*******************************************************************
2793 set the horrid remote_arch string based on an enum.
2794 ********************************************************************/
2796 set_remote_arch (enum remote_arch_types type
)
2802 remote_arch
= "WfWg";
2805 remote_arch
= "OS2";
2808 remote_arch
= "Win95";
2811 remote_arch
= "WinNT";
2814 remote_arch
= "Samba";
2817 ra_type
= RA_UNKNOWN
;
2818 remote_arch
= "UNKNOWN";
2823 /*******************************************************************
2824 Get the remote_arch type.
2825 ********************************************************************/
2826 enum remote_arch_types
2827 get_remote_arch (void)
2833 /*******************************************************************
2834 align a pointer to a multiple of 2 bytes
2835 ********************************************************************/
2837 align2 (char *q
, char *base
)
2847 out_ascii (FILE * f
, unsigned char *buf
, int len
)
2850 for (i
= 0; i
< len
; i
++)
2852 fprintf (f
, "%c", isprint (buf
[i
]) ? buf
[i
] : '.');
2857 out_data (FILE * f
, char *buf1
, int len
, int per_line
)
2859 unsigned char *buf
= (unsigned char *) buf1
;
2866 fprintf (f
, "[%03X] ", i
);
2867 for (i
= 0; i
< len
;)
2869 fprintf (f
, "%02X ", (int) buf
[i
]);
2871 if (i
% (per_line
/ 2) == 0)
2873 if (i
% per_line
== 0)
2875 out_ascii (f
, &buf
[i
- per_line
], per_line
/ 2);
2877 out_ascii (f
, &buf
[i
- per_line
/ 2], per_line
/ 2);
2880 fprintf (f
, "[%03X] ", i
);
2883 if ((i
% per_line
) != 0)
2887 n
= per_line
- (i
% per_line
);
2889 if (n
> (per_line
/ 2))
2895 n
= MIN (per_line
/ 2, i
% per_line
);
2896 out_ascii (f
, &buf
[i
- (i
% per_line
)], n
);
2898 n
= (i
% per_line
) - n
;
2900 out_ascii (f
, &buf
[i
- n
], n
);
2907 print_asc (int level
, unsigned char *buf
, int len
)
2910 for (i
= 0; i
< len
; i
++)
2911 DEBUG (level
, ("%c", isprint (buf
[i
]) ? buf
[i
] : '.'));
2915 dump_data (int level
, char *buf1
, int len
)
2917 unsigned char *buf
= (unsigned char *) buf1
;
2922 DEBUG (level
, ("[%03X] ", i
));
2923 for (i
= 0; i
< len
;)
2925 DEBUG (level
, ("%02X ", (int) buf
[i
]));
2928 DEBUG (level
, (" "));
2931 print_asc (level
, &buf
[i
- 16], 8);
2932 DEBUG (level
, (" "));
2933 print_asc (level
, &buf
[i
- 8], 8);
2934 DEBUG (level
, ("\n"));
2936 DEBUG (level
, ("[%03X] ", i
));
2944 DEBUG (level
, (" "));
2946 DEBUG (level
, (" "));
2948 DEBUG (level
, (" "));
2950 n
= MIN (8, i
% 16);
2951 print_asc (level
, &buf
[i
- (i
% 16)], n
);
2952 DEBUG (level
, (" "));
2955 print_asc (level
, &buf
[i
- n
], n
);
2956 DEBUG (level
, ("\n"));
2961 /*****************************************************************************
2962 * Provide a checksum on a string
2964 * Input: s - the null-terminated character string for which the checksum
2965 * will be calculated.
2967 * Output: The checksum value calculated for s.
2969 * ****************************************************************************
2972 str_checksum (const char *s
)
2981 res
^= (c
<< (i
% 15)) ^ (c
>> (15 - (i
% 15)));
2986 } /* str_checksum */
2989 /*****************************************************************
2990 zero a memory area then free it. Used to catch bugs faster
2991 *****************************************************************/
2993 zero_free (void *p
, size_t size
)
2995 memset (p
, 0, size
);