2 Unix SMB/Netbios implementation.
4 Samba utility functions
6 Copyright (C) Andrew Tridgell 1992-1998
9 The 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 */
66 extern int DEBUGLEVEL
;
68 int Protocol
= PROTOCOL_COREPLUS
;
71 /* a default finfo structure to ensure all fields are sensible */
72 file_info
const def_finfo
= { -1, 0, 0, 0, 0, 0, 0, "" };
74 /* the client file descriptor */
77 /* this is used by the chaining code */
78 const int chain_size
= 0;
84 case handling on filenames
86 const int case_default
= CASE_LOWER
;
89 /* the following control case operations - they are put here so the
90 client can link easily */
93 BOOL use_mangled_map
= False
;
94 BOOL short_case_preserve
;
98 static const char *remote_machine
= "";
99 static const char *local_machine
= "";
100 static const char *remote_arch
= "UNKNOWN";
102 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
104 static const char *remote_proto
= "UNKNOWN";
105 pstring myhostname
= "";
106 pstring user_socket_options
= "";
108 pstring sesssetup_user
= "";
109 static const char *const samlogon_user
= "";
111 const BOOL sam_logon_in_ssb
= False
;
113 pstring global_myname
= "";
115 char **my_netbios_names
;
119 /****************************************************************************
120 find a suitable temporary directory. The result should be copied immediately
121 as it may be overwritten by a subsequent call
122 ****************************************************************************/
127 if ((p
= getenv ("MC_TMPDIR")) || (p
= getenv ("TMPDIR")))
134 /****************************************************************************
135 determine whether we are in the specified group
136 ****************************************************************************/
139 in_group (gid_t group
, gid_t current_gid
, int ngroups
, gid_t
* groups
)
143 if (group
== current_gid
)
146 for (i
= 0; i
< ngroups
; i
++)
147 if (group
== groups
[i
])
154 /****************************************************************************
155 like atoi but gets the value up to the separater character
156 ****************************************************************************/
158 Atoic (char *p
, int *n
, char *c
)
160 if (!isdigit ((int) *p
))
162 DEBUG (5, ("Atoic: malformed number\n"));
168 while ((*p
) && isdigit ((int) *p
))
173 if (strchr (c
, *p
) == NULL
)
175 DEBUG (5, ("Atoic: no separator characters (%s) not found\n", c
));
182 /*************************************************************************
183 reads a list of numbers
184 *************************************************************************/
186 get_numlist (char *p
, uint32
** num
, int *count
)
190 if (num
== NULL
|| count
== NULL
)
198 while ((p
= Atoic (p
, &val
, ":,")) != NULL
&& (*p
) != ':')
200 (*num
) = Realloc ((*num
), ((*count
) + 1) * sizeof (uint32
));
205 (*num
)[(*count
)] = val
;
213 /*******************************************************************
214 copy an IP address from one buffer to another
215 ********************************************************************/
217 putip (void *dest
, void *src
)
219 memcpy (dest
, src
, 4);
223 #define TRUNCATE_NETBIOS_NAME 1
225 /*******************************************************************
226 convert, possibly using a stupid microsoft-ism which has destroyed
227 the transport independence of netbios (for CIFS vendors that usually
228 use the Win95-type methods, not for NT to NT communication, which uses
229 DCE/RPC and therefore full-length unicode strings...) a dns name into
232 the netbios name (NOT necessarily null-terminated) is truncated to 15
235 ******************************************************************/
237 dns_to_netbios_name (char *dns_name
)
239 static char netbios_name
[16];
241 StrnCpy (netbios_name
, dns_name
, 15);
242 netbios_name
[15] = 0;
244 #ifdef TRUNCATE_NETBIOS_NAME
245 /* ok. this is because of a stupid microsoft-ism. if the called host
246 name contains a '.', microsoft clients expect you to truncate the
247 netbios name up to and including the '.' this even applies, by
248 mistake, to workgroup (domain) names, which is _really_ daft.
250 for (i
= 15; i
>= 0; i
--)
252 if (netbios_name
[i
] == '.')
258 #endif /* TRUNCATE_NETBIOS_NAME */
264 /****************************************************************************
265 interpret the weird netbios "name". Return the name type
266 ****************************************************************************/
268 name_interpret (char *in
, char *out
)
271 int len
= (*in
++) / 2;
275 if (len
> 30 || len
< 1)
280 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P')
285 *out
= ((in
[0] - 'A') << 4) + (in
[1] - 'A');
293 /* Handle any scope names */
296 *out
++ = '.'; /* Scope names are separated by periods */
297 len
= *(unsigned char *) in
++;
298 StrnCpy (out
, in
, len
);
308 /****************************************************************************
309 mangle a name into netbios format
311 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
312 ****************************************************************************/
314 name_mangle (char *In
, char *Out
, char name_type
)
321 extern pstring global_scope
;
323 /* Safely copy the input string, In, into buf[]. */
324 (void) memset (buf
, 0, 20);
325 if (strcmp (In
, "*") == 0)
328 (void) slprintf (buf
, sizeof (buf
) - 1, "%-15.15s%c", In
, name_type
);
330 /* Place the length of the first field into the output buffer. */
334 /* Now convert the name to the rfc1001/1002 format. */
335 for (i
= 0; i
< 16; i
++)
337 c
= toupper (buf
[i
]);
338 p
[i
* 2] = ((c
>> 4) & 0x000F) + 'A';
339 p
[(i
* 2) + 1] = (c
& 0x000F) + 'A';
344 /* Add the scope string. */
345 for (i
= 0, len
= 0; NULL
!= global_scope
; i
++, len
++)
347 switch (global_scope
[i
])
353 return (name_len (Out
));
360 p
[len
+ 1] = global_scope
[i
];
365 return (name_len (Out
));
368 /*******************************************************************
369 check if a file exists
370 ********************************************************************/
372 file_exist (char *fname
, SMB_STRUCT_STAT
* sbuf
)
378 if (sys_stat (fname
, sbuf
) != 0)
381 return (S_ISREG (sbuf
->st_mode
));
384 /*******************************************************************
385 check a files mod time
386 ********************************************************************/
388 file_modtime (char *fname
)
392 if (sys_stat (fname
, &st
) != 0)
395 return (st
.st_mtime
);
399 /*******************************************************************
400 check if a directory exists
401 ********************************************************************/
403 directory_exist (char *dname
, SMB_STRUCT_STAT
* st
)
411 if (sys_stat (dname
, st
) != 0)
414 ret
= S_ISDIR (st
->st_mode
);
420 /*******************************************************************
421 returns the size in bytes of the named file
422 ********************************************************************/
424 file_size (char *file_name
)
428 if (sys_stat (file_name
, &buf
) != 0)
429 return (SMB_OFF_T
) - 1;
430 return (buf
.st_size
);
434 /*******************************************************************
435 return a string representing an attribute for a file
436 ********************************************************************/
438 attrib_string (uint16 mode
)
440 static fstring attrstr
;
445 fstrcat (attrstr
, "V");
447 fstrcat (attrstr
, "D");
449 fstrcat (attrstr
, "A");
451 fstrcat (attrstr
, "H");
453 fstrcat (attrstr
, "S");
455 fstrcat (attrstr
, "R");
461 /****************************************************************************
462 make a file into unix format
463 ****************************************************************************/
465 unix_format (char *fname
)
467 string_replace (fname
, '\\', '/');
470 /****************************************************************************
471 make a file into dos format
472 ****************************************************************************/
474 dos_format (char *fname
)
476 string_replace (fname
, '/', '\\');
479 /*******************************************************************
480 show a smb message structure
481 ********************************************************************/
492 ("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
493 smb_len (buf
), (int) CVAL (buf
, smb_com
), (int) CVAL (buf
, smb_rcls
), (int) CVAL (buf
,
495 (int) SVAL (buf
, smb_err
), (int) CVAL (buf
, smb_flg
), (int) SVAL (buf
, smb_flg2
)));
497 ("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
498 (int) SVAL (buf
, smb_tid
), (int) SVAL (buf
, smb_pid
), (int) SVAL (buf
, smb_uid
),
499 (int) SVAL (buf
, smb_mid
), (int) CVAL (buf
, smb_wct
)));
501 for (i
= 0; i
< (int) CVAL (buf
, smb_wct
); i
++)
503 DEBUG (5, ("smb_vwv[%d]=%d (0x%X)\n", i
,
504 SVAL (buf
, smb_vwv
+ 2 * i
), SVAL (buf
, smb_vwv
+ 2 * i
)));
507 bcc
= (int) SVAL (buf
, smb_vwv
+ 2 * (CVAL (buf
, smb_wct
)));
509 DEBUG (5, ("smb_bcc=%d\n", bcc
));
516 bcc
= MIN (bcc
, 512);
519 dump_data (10, smb_buf (buf
), bcc
);
522 /*******************************************************************
523 return the length of an smb packet
524 ********************************************************************/
528 return (PVAL (buf
, 3) | (PVAL (buf
, 2) << 8) | ((PVAL (buf
, 1) & 1) << 16));
531 /*******************************************************************
532 set the length of an smb packet
533 ********************************************************************/
535 _smb_setlen (char *buf
, int len
)
538 buf
[1] = (len
& 0x10000) >> 16;
539 buf
[2] = (len
& 0xFF00) >> 8;
543 /*******************************************************************
544 set the length and marker of an smb packet
545 ********************************************************************/
547 smb_setlen (char *buf
, int len
)
549 _smb_setlen (buf
, len
);
551 CVAL (buf
, 4) = 0xFF;
557 /*******************************************************************
558 setup the word count and byte count for a smb message
559 ********************************************************************/
561 set_message (char *buf
, int num_words
, int num_bytes
, BOOL zero
)
564 memset (buf
+ smb_size
, '\0', num_words
* 2 + num_bytes
);
565 CVAL (buf
, smb_wct
) = num_words
;
566 SSVAL (buf
, smb_vwv
+ num_words
* SIZEOFWORD
, num_bytes
);
567 smb_setlen (buf
, smb_size
+ num_words
* 2 + num_bytes
- 4);
568 return (smb_size
+ num_words
* 2 + num_bytes
);
571 /*******************************************************************
572 return the number of smb words
573 ********************************************************************/
575 smb_numwords (char *buf
)
577 return (CVAL (buf
, smb_wct
));
580 /*******************************************************************
581 return the size of the smb_buf region of a message
582 ********************************************************************/
584 smb_buflen (char *buf
)
586 return (SVAL (buf
, smb_vwv0
+ smb_numwords (buf
) * 2));
589 /*******************************************************************
590 return a pointer to the smb_buf data area
591 ********************************************************************/
593 smb_buf_ofs (char *buf
)
595 return (smb_size
+ CVAL (buf
, smb_wct
) * 2);
598 /*******************************************************************
599 return a pointer to the smb_buf data area
600 ********************************************************************/
604 return (buf
+ smb_buf_ofs (buf
));
607 /*******************************************************************
608 return the SMB offset into an SMB buffer
609 ********************************************************************/
611 smb_offset (char *p
, char *buf
)
613 return (PTR_DIFF (p
, buf
+ 4) + chain_size
);
617 /*******************************************************************
618 reduce a file name, removing .. elements.
619 ********************************************************************/
621 dos_clean_name (char *s
)
625 DEBUG (3, ("dos_clean_name [%s]\n", s
));
627 /* remove any double slashes */
628 string_sub (s
, "\\\\", "\\");
630 while ((p
= strstr (s
, "\\..\\")) != NULL
)
637 if ((p
= strrchr (s
, '\\')) != NULL
)
644 trim_string (s
, NULL
, "\\..");
646 string_sub (s
, "\\.\\", "\\");
649 /*******************************************************************
650 reduce a file name, removing .. elements.
651 ********************************************************************/
653 unix_clean_name (char *s
)
657 DEBUG (3, ("unix_clean_name [%s]\n", s
));
659 /* remove any double slashes */
660 string_sub (s
, "//", "/");
662 /* Remove leading ./ characters */
663 if (strncmp (s
, "./", 2) == 0)
665 trim_string (s
, "./", NULL
);
670 while ((p
= strstr (s
, "/../")) != NULL
)
677 if ((p
= strrchr (s
, '/')) != NULL
)
684 trim_string (s
, NULL
, "/..");
687 /*******************************************************************
688 reduce a file name, removing .. elements and checking that
689 it is below dir in the heirachy. This uses dos_GetWd() and so must be run
690 on the system that has the referenced file system.
692 widelinks are allowed if widelinks is true
693 ********************************************************************/
695 reduce_name (char *s
, char *dir
, BOOL widelinks
)
705 BOOL relative
= (*s
!= '/');
707 *dir2
= *wd
= *base_name
= *newname
= 0;
712 /* can't have a leading .. */
713 if (strncmp (s
, "..", 2) == 0 && (s
[2] == 0 || s
[2] == '/'))
715 DEBUG (3, ("Illegal file name? (%s)\n", s
));
725 DEBUG (3, ("reduce_name [%s] [%s]\n", s
, dir
));
727 /* remove any double slashes */
728 string_sub (s
, "//", "/");
730 pstrcpy (base_name
, s
);
731 p
= strrchr (base_name
, '/');
738 DEBUG (0, ("couldn't getwd for %s %s\n", s
, dir
));
742 if (dos_ChDir (dir
) != 0)
744 DEBUG (0, ("couldn't chdir to %s\n", dir
));
748 if (!dos_GetWd (dir2
))
750 DEBUG (0, ("couldn't getwd for %s\n", dir
));
755 if (p
&& (p
!= base_name
))
758 if (strcmp (p
+ 1, ".") == 0)
760 if (strcmp (p
+ 1, "..") == 0)
764 if (dos_ChDir (base_name
) != 0)
767 DEBUG (3, ("couldn't chdir for %s %s basename=%s\n", s
, dir
, base_name
));
771 if (!dos_GetWd (newname
))
774 DEBUG (2, ("couldn't get wd for %s %s\n", s
, dir2
));
778 if (p
&& (p
!= base_name
))
780 pstrcat (newname
, "/");
781 pstrcat (newname
, p
+ 1);
785 size_t l
= strlen (dir2
);
786 if (dir2
[l
- 1] == '/')
789 if (strncmp (newname
, dir2
, l
) != 0)
793 ("Bad access attempt? s=%s dir=%s newname=%s l=%d\n", s
, dir2
, newname
,
800 if (newname
[l
] == '/')
801 pstrcpy (s
, newname
+ l
+ 1);
803 pstrcpy (s
, newname
+ l
);
806 pstrcpy (s
, newname
);
814 DEBUG (3, ("reduced to %s\n", s
));
820 /****************************************************************************
822 ****************************************************************************/
824 expand_one (char *Mask
, int len
)
827 while ((p1
= strchr (Mask
, '*')) != NULL
)
829 int lfill
= (len
+ 1) - strlen (Mask
);
830 int l1
= (p1
- Mask
);
833 memset (tmp
+ l1
, '?', lfill
);
834 pstrcpy (tmp
+ l1
+ lfill
, Mask
+ l1
+ 1);
839 /****************************************************************************
840 parse out a directory name from a path name. Assumes dos style filenames.
841 ****************************************************************************/
843 dirname_dos (char *path
, char *buf
)
845 split_at_last_component (path
, buf
, '\\', NULL
);
849 /****************************************************************************
850 parse out a filename from a path name. Assumes dos style filenames.
851 ****************************************************************************/
853 filename_dos (char *path
, char *buf
)
855 char *p
= strrchr (path
, '\\');
860 pstrcpy (buf
, p
+ 1);
865 /****************************************************************************
866 expand a wildcard expression, replacing *s with ?s
867 ****************************************************************************/
869 expand_mask (char *Mask
, BOOL doext
)
876 BOOL absolute
= (*Mask
== '\\');
878 *mbeg
= *mext
= *dirpart
= *filepart
= 0;
880 /* parse the directory and filename */
881 if (strchr (Mask
, '\\'))
882 dirname_dos (Mask
, dirpart
);
884 filename_dos (Mask
, filepart
);
886 pstrcpy (mbeg
, filepart
);
887 if ((p1
= strchr (mbeg
, '.')) != NULL
)
897 if (strlen (mbeg
) > 8)
899 pstrcpy (mext
, mbeg
+ 8);
905 pstrcpy (mbeg
, "????????");
906 if ((*mext
== 0) && doext
&& !hasdot
)
907 pstrcpy (mext
, "???");
909 if (strequal (mbeg
, "*") && *mext
== 0)
913 expand_one (mbeg
, 8);
915 expand_one (mext
, 3);
917 pstrcpy (Mask
, dirpart
);
918 if (*dirpart
|| absolute
)
919 pstrcat (Mask
, "\\");
920 pstrcat (Mask
, mbeg
);
922 pstrcat (Mask
, mext
);
924 DEBUG (6, ("Mask expanded to [%s]\n", Mask
));
928 /****************************************************************************
930 ****************************************************************************/
932 make_dir_struct (char *buf
, char *mask
, char *fname
, SMB_OFF_T size
, int mode
, time_t date
)
937 pstrcpy (mask2
, mask
);
939 if ((mode
& aDIR
) != 0)
942 memset (buf
+ 1, ' ', 11);
943 if ((p
= strchr (mask2
, '.')) != NULL
)
946 memcpy (buf
+ 1, mask2
, MIN (strlen (mask2
), 8));
947 memcpy (buf
+ 9, p
+ 1, MIN (strlen (p
+ 1), 3));
951 memcpy (buf
+ 1, mask2
, MIN (strlen (mask2
), 11));
953 memset (buf
+ 21, '\0', DIR_STRUCT_SIZE
- 21);
954 CVAL (buf
, 21) = mode
;
955 put_dos_date (buf
, 22, date
);
956 SSVAL (buf
, 26, size
& 0xFFFF);
957 SSVAL (buf
, 28, (size
>> 16) & 0xFFFF);
958 StrnCpy (buf
+ 30, fname
, 12);
961 DEBUG (8, ("put name [%s] into dir struct\n", buf
+ 30));
965 /*******************************************************************
966 close the low 3 fd's and open dev/null in their place
967 ********************************************************************/
976 /* try and use up these file descriptors, so silly
977 library routines writing to stdout etc won't cause havoc */
978 for (i
= 0; i
< 3; i
++)
980 fd
= sys_open ("/dev/null", O_RDWR
, 0);
982 fd
= sys_open ("/dev/null", O_WRONLY
, 0);
985 DEBUG (0, ("Cannot open /dev/null\n"));
990 DEBUG (0, ("Didn't get file descriptor %d\n", i
));
997 /****************************************************************************
998 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1000 if SYSV use O_NDELAY
1002 ****************************************************************************/
1004 set_blocking (int fd
, BOOL set
)
1008 #define FLAG_TO_SET O_NONBLOCK
1011 #define FLAG_TO_SET O_NDELAY
1013 #define FLAG_TO_SET FNDELAY
1017 if ((val
= fcntl (fd
, F_GETFL
, 0)) == -1)
1019 if (set
) /* Turn blocking on - ie. clear nonblock flag */
1020 val
&= ~FLAG_TO_SET
;
1023 return fcntl (fd
, F_SETFL
, val
);
1028 /*******************************************************************
1029 find the difference in milliseconds between two struct timeval
1031 ********************************************************************/
1033 TvalDiff (struct timeval
*tvalold
, struct timeval
*tvalnew
)
1035 return ((tvalnew
->tv_sec
- tvalold
->tv_sec
) * 1000 +
1036 ((int) tvalnew
->tv_usec
- (int) tvalold
->tv_usec
) / 1000);
1041 /****************************************************************************
1042 transfer some data between two fd's
1043 ****************************************************************************/
1045 transfer_file (int infd
, int outfd
, SMB_OFF_T n
, char *header
, int headlen
, int align
)
1047 static char *buf
= NULL
;
1048 static int size
= 0;
1050 SMB_OFF_T total
= 0;
1052 DEBUG (4, ("transfer_file n=%.0f (head=%d) called\n", (double) n
, headlen
));
1056 size
= lp_readsize ();
1057 size
= MAX (size
, 1024);
1060 while (!buf
&& size
> 0)
1062 buf
= (char *) Realloc (buf
, size
+ 8);
1069 DEBUG (0, ("Cannot allocate transfer buffer!\n"));
1073 abuf
= buf
+ (align
% 8);
1080 int s
= (int) MIN (n
, (SMB_OFF_T
) size
);
1085 if (header
&& (headlen
>= MIN (s
, 1024)))
1098 if (header
&& headlen
> 0)
1100 ret
= MIN (headlen
, size
);
1101 memcpy (buf1
, header
, ret
);
1109 ret
+= read (infd
, buf1
+ ret
, s
- ret
);
1113 ret2
= (outfd
>= 0 ? write_data (outfd
, buf1
, ret
) : ret
);
1116 /* if we can't write then dump excess data */
1118 transfer_file (infd
, -1, n
- (ret
+ headlen
), NULL
, 0, 0);
1120 if (ret
<= 0 || ret2
!= ret
)
1128 /****************************************************************************
1129 find a pointer to a netbios name
1130 ****************************************************************************/
1132 name_ptr (char *buf
, int ofs
)
1134 unsigned char c
= *(unsigned char *) (buf
+ ofs
);
1136 if ((c
& 0xC0) == 0xC0)
1140 memcpy (p
, buf
+ ofs
, 2);
1143 DEBUG (5, ("name ptr to pos %d from %d is %s\n", l
, ofs
, buf
+ l
));
1150 /****************************************************************************
1151 extract a netbios name from a buf
1152 ****************************************************************************/
1154 name_extract (char *buf
, int ofs
, char *name
)
1156 char *p
= name_ptr (buf
, ofs
);
1157 int d
= PTR_DIFF (p
, buf
+ ofs
);
1159 if (d
< -50 || d
> 50)
1161 return (name_interpret (p
, name
));
1165 /****************************************************************************
1166 return the total storage length of a mangled name
1167 ****************************************************************************/
1171 /* NOTE: this argument _must_ be unsigned */
1172 unsigned char *s
= (unsigned char *) s1
;
1175 /* If the two high bits of the byte are set, return 2. */
1176 if (0xC0 == (*s
& 0xC0))
1179 /* Add up the length bytes. */
1180 for (len
= 1; (*s
); s
+= (*s
) + 1)
1183 SMB_ASSERT (len
< 80);
1190 /*******************************************************************
1191 sleep for a specified number of milliseconds
1192 ********************************************************************/
1197 struct timeval tval
, t1
, t2
;
1205 tval
.tv_sec
= (t
- tdiff
) / 1000;
1206 tval
.tv_usec
= 1000 * ((t
- tdiff
) % 1000);
1210 sys_select (0, &fds
, &tval
);
1213 tdiff
= TvalDiff (&t1
, &t2
);
1218 /*********************************************************
1219 * Recursive routine that is called by unix_mask_match.
1220 * Does the actual matching. This is the 'original code'
1221 * used by the unix matcher.
1222 *********************************************************/
1224 unix_do_match (char *str
, char *regexp
, int case_sig
)
1228 for (p
= regexp
; *p
&& *str
;)
1238 /* Look for a character matching
1239 the one after the '*' */
1242 return True
; /* Automatic match */
1245 while (*str
&& (case_sig
? (*p
!= *str
) : (toupper (*p
) != toupper (*str
))))
1247 if (unix_do_match (str
, p
, case_sig
))
1264 if (toupper (*str
) != toupper (*p
))
1274 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1277 if (!*str
&& *p
== '?')
1284 if (!*str
&& (*p
== '*' && p
[1] == '\0'))
1290 /*********************************************************
1291 * Routine to match a given string with a regexp - uses
1292 * simplified regexp that takes * and ? only. Case can be
1293 * significant or not.
1294 * This is the 'original code' used by the unix matcher.
1295 *********************************************************/
1298 unix_mask_match (char *str
, char *regexp
, int case_sig
, BOOL trans2
)
1302 fstring ebase
, eext
, sbase
, sext
;
1306 /* Make local copies of str and regexp */
1307 StrnCpy (p1
, regexp
, sizeof (pstring
) - 1);
1308 StrnCpy (p2
, str
, sizeof (pstring
) - 1);
1310 if (!strchr (p2
, '.'))
1315 /* Remove any *? and ** as they are meaningless */
1316 for (p
= p1
; *p
; p
++)
1317 while (*p
== '*' && (p
[1] == '?' || p
[1] == '*'))
1318 (void) pstrcpy (&p
[1], &p
[2]);
1320 if (strequal (p1
, "*"))
1323 DEBUG (8, ("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
1327 fstrcpy (ebase
, p1
);
1328 fstrcpy (sbase
, p2
);
1332 if ((p
= strrchr (p1
, '.')))
1335 fstrcpy (ebase
, p1
);
1336 fstrcpy (eext
, p
+ 1);
1340 fstrcpy (ebase
, p1
);
1344 if (!strequal (p2
, ".") && !strequal (p2
, "..") && (p
= strrchr (p2
, '.')))
1347 fstrcpy (sbase
, p2
);
1348 fstrcpy (sext
, p
+ 1);
1352 fstrcpy (sbase
, p2
);
1357 matched
= unix_do_match (sbase
, ebase
, case_sig
) &&
1358 (trans2
|| unix_do_match (sext
, eext
, case_sig
));
1360 DEBUG (8, ("unix_mask_match returning %d\n", matched
));
1365 /*********************************************************
1366 * Recursive routine that is called by mask_match.
1367 * Does the actual matching. Returns True if matched,
1368 * False if failed. This is the 'new' NT style matcher.
1369 *********************************************************/
1372 do_match (char *str
, char *regexp
, int case_sig
)
1376 for (p
= regexp
; *p
&& *str
;)
1386 /* Look for a character matching
1387 the one after the '*' */
1390 return True
; /* Automatic match */
1393 while (*str
&& (case_sig
? (*p
!= *str
) : (toupper (*p
) != toupper (*str
))))
1395 /* Now eat all characters that match, as
1396 we want the *last* character to match. */
1397 while (*str
&& (case_sig
? (*p
== *str
) : (toupper (*p
) == toupper (*str
))))
1399 str
--; /* We've eaten the match char after the '*' */
1400 if (do_match (str
, p
, case_sig
))
1425 if (toupper (*str
) != toupper (*p
))
1438 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1443 if (!*str
&& *p
== '?')
1450 if (!*str
&& (*p
== '*' && p
[1] == '\0'))
1459 /*********************************************************
1460 * Routine to match a given string with a regexp - uses
1461 * simplified regexp that takes * and ? only. Case can be
1462 * significant or not.
1463 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
1464 * This is the new 'NT style' matcher.
1465 *********************************************************/
1468 mask_match (char *str
, char *regexp
, int case_sig
, BOOL trans2
)
1471 pstring t_pattern
, t_filename
, te_pattern
, te_filename
;
1472 fstring ebase
, eext
, sbase
, sext
;
1474 BOOL matched
= False
;
1476 /* Make local copies of str and regexp */
1477 pstrcpy (t_pattern
, regexp
);
1478 pstrcpy (t_filename
, str
);
1483 /* a special case for 16 bit apps */
1484 if (strequal (t_pattern
, "????????.???"))
1485 pstrcpy (t_pattern
, "*");
1489 * Handle broken clients that send us old 8.3 format.
1491 string_sub (t_pattern
, "????????", "*");
1492 string_sub (t_pattern
, ".???", ".*");
1498 * Not sure if this is a good idea. JRA.
1500 if (trans2
&& is_8_3 (t_pattern
, False
) && is_8_3 (t_filename
, False
))
1505 if (!strchr (t_filename
, '.'))
1507 pstrcat (t_filename
, ".");
1511 /* Remove any *? and ** as they are meaningless */
1512 string_sub (t_pattern
, "*?", "*");
1513 string_sub (t_pattern
, "**", "*");
1515 if (strequal (t_pattern
, "*"))
1519 ("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename
, t_pattern
, case_sig
));
1524 * Match each component of the regexp, split up by '.'
1527 char *fp
, *rp
, *cp2
, *cp1
;
1528 BOOL last_wcard_was_star
= False
;
1529 int num_path_components
, num_regexp_components
;
1531 pstrcpy (te_pattern
, t_pattern
);
1532 pstrcpy (te_filename
, t_filename
);
1534 * Remove multiple "*." patterns.
1536 string_sub (te_pattern
, "*.*.", "*.");
1537 num_regexp_components
= count_chars (te_pattern
, '.');
1538 num_path_components
= count_chars (te_filename
, '.');
1541 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
1543 if (num_regexp_components
== 0)
1544 matched
= do_match (te_filename
, te_pattern
, case_sig
);
1547 for (cp1
= te_pattern
, cp2
= te_filename
; cp1
;)
1549 fp
= strchr (cp2
, '.');
1552 rp
= strchr (cp1
, '.');
1556 if (cp1
[strlen (cp1
) - 1] == '*')
1557 last_wcard_was_star
= True
;
1559 last_wcard_was_star
= False
;
1561 if (!do_match (cp2
, cp1
, case_sig
))
1564 cp1
= rp
? rp
+ 1 : NULL
;
1565 cp2
= fp
? fp
+ 1 : "";
1567 if (last_wcard_was_star
|| ((cp1
!= NULL
) && (*cp1
== '*')))
1569 /* Eat the extra path components. */
1572 for (i
= 0; i
< num_path_components
- num_regexp_components
; i
++)
1574 fp
= strchr (cp2
, '.');
1578 if ((cp1
!= NULL
) && do_match (cp2
, cp1
, case_sig
))
1580 cp2
= fp
? fp
+ 1 : "";
1583 cp2
= fp
? fp
+ 1 : "";
1585 num_path_components
-= i
;
1588 if (cp1
== NULL
&& ((*cp2
== '\0') || last_wcard_was_star
))
1595 /* -------------------------------------------------
1596 * Behaviour of Win95
1597 * for 8.3 filenames and 8.3 Wildcards
1598 * -------------------------------------------------
1600 if (strequal (t_filename
, "."))
1603 * Patterns: *.* *. ?. ? ????????.??? are valid.
1606 if (strequal (t_pattern
, "*.*") || strequal (t_pattern
, "*.") ||
1607 strequal (t_pattern
, "????????.???") ||
1608 strequal (t_pattern
, "?.") || strequal (t_pattern
, "?"))
1611 else if (strequal (t_filename
, ".."))
1614 * Patterns: *.* *. ?. ? *.? ????????.??? are valid.
1617 if (strequal (t_pattern
, "*.*") || strequal (t_pattern
, "*.") ||
1618 strequal (t_pattern
, "?.") || strequal (t_pattern
, "?") ||
1619 strequal (t_pattern
, "????????.???") ||
1620 strequal (t_pattern
, "*.?") || strequal (t_pattern
, "?.*"))
1626 if ((p
= strrchr (t_pattern
, '.')))
1629 * Wildcard has a suffix.
1632 fstrcpy (ebase
, t_pattern
);
1635 fstrcpy (eext
, p
+ 1);
1639 /* pattern ends in DOT: treat as if there is no DOT */
1641 if (strequal (ebase
, "*"))
1648 * No suffix for wildcard.
1650 fstrcpy (ebase
, t_pattern
);
1654 p
= strrchr (t_filename
, '.');
1655 if (p
&& (p
[1] == 0))
1658 * Filename has an extension of '.' only.
1660 *p
= 0; /* nuke dot at end of string */
1661 p
= 0; /* and treat it as if there is no extension */
1667 * Filename has an extension.
1670 fstrcpy (sbase
, t_filename
);
1671 fstrcpy (sext
, p
+ 1);
1674 matched
= do_match (sbase
, ebase
, case_sig
) && do_match (sext
, eext
, case_sig
);
1678 /* pattern has no extension */
1679 /* Really: match complete filename with pattern ??? means exactly 3 chars */
1680 matched
= do_match (str
, ebase
, case_sig
);
1686 * Filename has no extension.
1688 fstrcpy (sbase
, t_filename
);
1692 /* pattern has extension */
1693 matched
= do_match (sbase
, ebase
, case_sig
) && do_match (sext
, eext
, case_sig
);
1697 matched
= do_match (sbase
, ebase
, case_sig
);
1698 #ifdef EMULATE_WEIRD_W95_MATCHING
1700 * Even Microsoft has some problems
1701 * Behaviour Win95 -> local disk
1702 * is different from Win95 -> smb drive from Nt 4.0
1703 * This branch would reflect the Win95 local disk behaviour
1707 /* a? matches aa and a in w95 */
1708 fstrcat (sbase
, ".");
1709 matched
= do_match (sbase
, ebase
, case_sig
);
1717 DEBUG (8, ("mask_match returning %d\n", matched
));
1724 /****************************************************************************
1725 set the length of a file from a filedescriptor.
1726 Returns 0 on success, -1 on failure.
1727 ****************************************************************************/
1730 set_filelen (int fd
, SMB_OFF_T len
)
1732 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1733 extend a file with ftruncate. Provide alternate implementation
1736 #ifdef HAVE_FTRUNCATE_EXTEND
1737 return sys_ftruncate (fd
, len
);
1741 SMB_OFF_T currpos
= sys_lseek (fd
, (SMB_OFF_T
) 0, SEEK_CUR
);
1745 /* Do an fstat to see if the file is longer than
1746 the requested size (call ftruncate),
1747 or shorter, in which case seek to len - 1 and write 1
1749 if (sys_fstat (fd
, &st
) < 0)
1753 if (S_ISFIFO (st
.st_mode
))
1757 if (st
.st_size
== len
)
1759 if (st
.st_size
> len
)
1760 return sys_ftruncate (fd
, len
);
1762 if (sys_lseek (fd
, len
- 1, SEEK_SET
) != len
- 1)
1764 if (write (fd
, &c
, 1) != 1)
1766 /* Seek to where we were */
1767 if (sys_lseek (fd
, currpos
, SEEK_SET
) != currpos
)
1775 /****************************************************************************
1776 this is a version of setbuffer() for those machines that only have setvbuf
1777 ****************************************************************************/
1779 setbuffer (FILE * f
, char *buf
, int bufsize
)
1781 setvbuf (f
, buf
, _IOFBF
, bufsize
);
1788 /****************************************************************************
1789 expand a pointer to be a particular size
1790 ****************************************************************************/
1792 Realloc (void *p
, size_t size
)
1800 DEBUG (5, ("Realloc asked for 0 bytes\n"));
1805 ret
= (void *) malloc (size
);
1807 ret
= (void *) realloc (p
, size
);
1812 smb_mem_write_info (ret
, dbf
);
1817 DEBUG (0, ("Memory allocation error: failed to expand to %d bytes\n", (int) size
));
1823 /****************************************************************************
1824 get my own name and IP
1825 ****************************************************************************/
1827 get_myname (char *my_name
, struct in_addr
* ip
)
1834 /* get my host name */
1835 if (gethostname (hostname
, sizeof (hostname
)) == -1)
1837 DEBUG (0, ("gethostname failed\n"));
1841 /* Ensure null termination. */
1842 hostname
[sizeof (hostname
) - 1] = '\0';
1845 if ((hp
= Get_Hostbyname (hostname
)) == 0)
1847 DEBUG (0, ("Get_Hostbyname: Unknown host %s\n", hostname
));
1853 /* split off any parts after an initial . */
1854 char *p
= strchr (hostname
, '.');
1858 fstrcpy (my_name
, hostname
);
1862 putip ((char *) ip
, (char *) hp
->h_addr
);
1868 /****************************************************************************
1869 true if two IP addresses are equal
1870 ****************************************************************************/
1872 ip_equal (struct in_addr ip1
, struct in_addr ip2
)
1875 a1
= ntohl (ip1
.s_addr
);
1876 a2
= ntohl (ip2
.s_addr
);
1880 #if 0 /* May be useful one day */
1881 /****************************************************************************
1882 interpret a protocol description string, with a default
1883 ****************************************************************************/
1885 interpret_protocol (char *str
, int def
)
1887 if (strequal (str
, "NT1"))
1888 return (PROTOCOL_NT1
);
1889 if (strequal (str
, "LANMAN2"))
1890 return (PROTOCOL_LANMAN2
);
1891 if (strequal (str
, "LANMAN1"))
1892 return (PROTOCOL_LANMAN1
);
1893 if (strequal (str
, "CORE"))
1894 return (PROTOCOL_CORE
);
1895 if (strequal (str
, "COREPLUS"))
1896 return (PROTOCOL_COREPLUS
);
1897 if (strequal (str
, "CORE+"))
1898 return (PROTOCOL_COREPLUS
);
1900 DEBUG (0, ("Unrecognised protocol level %s\n", str
));
1906 /****************************************************************************
1907 interpret an internet address or name into an IP address in 4 byte form
1908 ****************************************************************************/
1910 interpret_addr (const char *str
)
1915 BOOL pure_address
= True
;
1917 if (strcmp (str
, "0.0.0.0") == 0)
1919 if (strcmp (str
, "255.255.255.255") == 0)
1920 return (0xFFFFFFFF);
1922 for (i
= 0; pure_address
&& str
[i
]; i
++)
1923 if (!(isdigit ((int) str
[i
]) || str
[i
] == '.'))
1924 pure_address
= False
;
1926 /* if it's in the form of an IP address then get the lib to interpret it */
1929 res
= inet_addr (str
);
1933 /* otherwise assume it's a network name of some sort and use
1935 if ((hp
= Get_Hostbyname (str
)) == 0)
1937 DEBUG (3, ("Get_Hostbyname: Unknown host. %s\n", str
));
1940 if (hp
->h_addr
== NULL
)
1942 DEBUG (3, ("Get_Hostbyname: host address is invalid for host %s\n", str
));
1945 putip ((char *) &res
, (char *) hp
->h_addr
);
1948 if (res
== (uint32
) - 1)
1954 /*******************************************************************
1955 a convenient addition to interpret_addr()
1956 ******************************************************************/
1958 interpret_addr2 (const char *str
)
1960 static struct in_addr ret
;
1961 uint32 a
= interpret_addr (str
);
1966 /*******************************************************************
1967 check if an IP is the 0.0.0.0
1968 ******************************************************************/
1970 zero_ip (struct in_addr ip
)
1973 putip ((char *) &a
, (char *) &ip
);
1978 /*******************************************************************
1979 matchname - determine if host name matches IP address
1980 ******************************************************************/
1982 matchname (char *remotehost
, struct in_addr addr
)
1987 if ((hp
= Get_Hostbyname (remotehost
)) == 0)
1989 DEBUG (0, ("Get_Hostbyname(%s): lookup failure.\n", remotehost
));
1994 * Make sure that gethostbyname() returns the "correct" host name.
1995 * Unfortunately, gethostbyname("localhost") sometimes yields
1996 * "localhost.domain". Since the latter host name comes from the
1997 * local DNS, we just have to trust it (all bets are off if the local
1998 * DNS is perverted). We always check the address list, though.
2001 if (strcasecmp (remotehost
, hp
->h_name
) && strcasecmp (remotehost
, "localhost"))
2003 DEBUG (0, ("host name/name mismatch: %s != %s\n", remotehost
, hp
->h_name
));
2007 /* Look up the host address in the address list we just got. */
2008 for (i
= 0; hp
->h_addr_list
[i
]; i
++)
2010 if (memcmp (hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof (addr
)) == 0)
2015 * The host name does not map to the original host address. Perhaps
2016 * someone has compromised a name server. More likely someone botched
2017 * it, but that could be dangerous, too.
2020 DEBUG (0, ("host name/address mismatch: %s != %s\n", inet_ntoa (addr
), hp
->h_name
));
2025 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
2026 /******************************************************************
2027 Remove any mount options such as -rsize=2048,wsize=2048 etc.
2028 Based on a fix from <Thomas.Hepper@icem.de>.
2029 *******************************************************************/
2032 strip_mount_options (pstring
* str
)
2037 while (*p
&& !isspace (*p
))
2039 while (*p
&& isspace (*p
))
2045 pstrcpy (tmp_str
, p
);
2046 pstrcpy (*str
, tmp_str
);
2051 /*******************************************************************
2052 Patch from jkf@soton.ac.uk
2053 Split Luke's automount_server into YP lookup and string splitter
2054 so can easily implement automount_path().
2055 As we may end up doing both, cache the last YP result.
2056 *******************************************************************/
2058 #ifdef WITH_NISPLUS_HOME
2060 automount_lookup (char *user_name
)
2062 static fstring last_key
= "";
2063 static pstring last_value
= "";
2065 char *nis_map
= (char *) lp_nis_home_map_name ();
2067 char buffer
[NIS_MAXATTRVAL
+ 1];
2072 DEBUG (5, ("NIS+ Domain: %s\n", (char *) nis_local_directory ()));
2074 if (strcmp (user_name
, last_key
))
2076 slprintf (buffer
, sizeof (buffer
) - 1, "[%s=%s]%s.%s", "key", user_name
, nis_map
,
2077 (char *) nis_local_directory ());
2078 DEBUG (5, ("NIS+ querystring: %s\n", buffer
));
2080 if (result
= nis_list (buffer
, RETURN_RESULT
, NULL
, NULL
))
2082 if (result
->status
!= NIS_SUCCESS
)
2084 DEBUG (3, ("NIS+ query failed: %s\n", nis_sperrno (result
->status
)));
2085 fstrcpy (last_key
, "");
2086 pstrcpy (last_value
, "");
2090 object
= result
->objects
.objects_val
;
2091 if (object
->zo_data
.zo_type
== ENTRY_OBJ
)
2093 entry
= &object
->zo_data
.objdata_u
.en_data
;
2094 DEBUG (5, ("NIS+ entry type: %s\n", entry
->en_type
));
2096 ("NIS+ result: %s\n",
2097 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
2099 pstrcpy (last_value
, entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
2100 string_sub (last_value
, "&", user_name
);
2101 fstrcpy (last_key
, user_name
);
2105 nis_freeresult (result
);
2108 strip_mount_options (&last_value
);
2110 DEBUG (4, ("NIS+ Lookup: %s resulted in %s\n", user_name
, last_value
));
2113 #else /* WITH_NISPLUS_HOME */
2115 automount_lookup (char *user_name
)
2117 static fstring last_key
= "";
2118 static pstring last_value
= "";
2120 int nis_error
; /* returned by yp all functions */
2121 char *nis_result
; /* yp_match inits this */
2122 int nis_result_len
; /* and set this */
2123 char *nis_domain
; /* yp_get_default_domain inits this */
2124 char *nis_map
= (char *) lp_nis_home_map_name ();
2126 if ((nis_error
= yp_get_default_domain (&nis_domain
)) != 0)
2128 DEBUG (3, ("YP Error: %s\n", yperr_string (nis_error
)));
2132 DEBUG (5, ("NIS Domain: %s\n", nis_domain
));
2134 if (!strcmp (user_name
, last_key
))
2136 nis_result
= last_value
;
2137 nis_result_len
= strlen (last_value
);
2142 if ((nis_error
= yp_match (nis_domain
, nis_map
,
2143 user_name
, strlen (user_name
),
2144 &nis_result
, &nis_result_len
)) != 0)
2146 DEBUG (3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
2147 yperr_string (nis_error
), user_name
, nis_map
));
2149 if (!nis_error
&& nis_result_len
>= sizeof (pstring
))
2151 nis_result_len
= sizeof (pstring
) - 1;
2153 fstrcpy (last_key
, user_name
);
2154 strncpy (last_value
, nis_result
, nis_result_len
);
2155 last_value
[nis_result_len
] = '\0';
2158 strip_mount_options (&last_value
);
2160 DEBUG (4, ("YP Lookup: %s resulted in %s\n", user_name
, last_value
));
2163 #endif /* WITH_NISPLUS_HOME */
2166 /*******************************************************************
2167 Patch from jkf@soton.ac.uk
2168 This is Luke's original function with the NIS lookup code
2169 moved out to a separate function.
2170 *******************************************************************/
2172 automount_server (const char *user_name
)
2174 static pstring server_name
;
2177 /* use the local machine name as the default */
2178 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2179 pstrcpy (server_name
, local_machine
);
2181 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2183 if (lp_nis_home_map ())
2185 int home_server_len
;
2186 char *automount_value
= automount_lookup (user_name
);
2187 home_server_len
= strcspn (automount_value
, ":");
2188 DEBUG (5, ("NIS lookup succeeded. Home server length: %d\n", home_server_len
));
2189 if (home_server_len
> sizeof (pstring
))
2191 home_server_len
= sizeof (pstring
);
2193 strncpy (server_name
, automount_value
, home_server_len
);
2194 server_name
[home_server_len
] = '\0';
2198 DEBUG (4, ("Home server: %s\n", server_name
));
2203 /*******************************************************************
2204 Patch from jkf@soton.ac.uk
2205 Added this to implement %p (NIS auto-map version of %H)
2206 *******************************************************************/
2208 automount_path (char *user_name
)
2210 static pstring server_path
;
2212 /* use the passwd entry as the default */
2213 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2214 /* pstrcpy() copes with get_home_dir() returning NULL */
2215 pstrcpy (server_path
, get_home_dir (user_name
));
2217 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2219 if (lp_nis_home_map ())
2221 char *home_path_start
;
2222 char *automount_value
= automount_lookup (user_name
);
2223 home_path_start
= strchr (automount_value
, ':');
2224 if (home_path_start
!= NULL
)
2226 DEBUG (5, ("NIS lookup succeeded. Home path is: %s\n",
2227 home_path_start
? (home_path_start
+ 1) : ""));
2228 pstrcpy (server_path
, home_path_start
+ 1);
2233 DEBUG (4, ("Home server path: %s\n", server_path
));
2239 /*******************************************************************
2240 sub strings with useful parameters
2241 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
2242 Paul Rippin <pr3245@nopc.eurostat.cec.be>
2243 ********************************************************************/
2245 standard_sub_basic (char *str
)
2249 struct passwd
*pass
;
2250 const char *username
= sam_logon_in_ssb
? samlogon_user
: sesssetup_user
;
2252 for (s
= str
; s
&& *s
&& (p
= strchr (s
, '%')); s
= p
)
2258 if ((pass
= Get_Pwnam (username
)) != NULL
)
2260 string_sub (p
, "%G", gidtoname (pass
->pw_gid
));
2269 string_sub (p
, "%N", automount_server (username
));
2272 string_sub (p
, "%I", client_addr (Client
));
2275 string_sub (p
, "%L", local_machine
);
2278 string_sub (p
, "%M", client_name (Client
));
2281 string_sub (p
, "%R", remote_proto
);
2284 string_sub (p
, "%T", timestring ());
2287 string_sub (p
, "%U", username
);
2290 string_sub (p
, "%a", remote_arch
);
2294 slprintf (pidstr
, sizeof (pidstr
) - 1, "%d", (int) getpid ());
2295 string_sub (p
, "%d", pidstr
);
2299 string_sub (p
, "%h", myhostname
);
2302 string_sub (p
, "%m", remote_machine
);
2305 string_sub (p
, "%v", VERSION
);
2307 case '$': /* Expand environment variables */
2309 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
2315 if (*(p
+ 2) != '(')
2320 if ((q
= strchr (p
, ')')) == NULL
)
2322 DEBUG (0, ("standard_sub_basic: Unterminated environment \
2323 variable [%s]\n", p
));
2329 copylen
= MIN ((size_t) (q
- r
), (size_t) (sizeof (envname
) - 1));
2330 strncpy (envname
, r
, copylen
);
2331 envname
[copylen
] = '\0';
2333 if ((envval
= getenv (envname
)) == NULL
)
2335 DEBUG (0, ("standard_sub_basic: Environment variable [%s] not set\n", envname
));
2340 copylen
= MIN ((size_t) (q
+ 1 - p
), (size_t) (sizeof (envname
) - 1));
2341 strncpy (envname
, p
, copylen
);
2342 envname
[copylen
] = '\0';
2343 string_sub (p
, envname
, envval
);
2348 break; /* don't run off end if last character is % */
2358 /****************************************************************************
2359 do some standard substitutions in a string
2360 ****************************************************************************/
2362 standard_sub (connection_struct
* conn
, char *str
)
2367 for (s
= str
; (p
= strchr (s
, '%')); s
= p
)
2372 if ((home
= get_home_dir (conn
->user
)))
2374 string_sub (p
, "%H", home
);
2383 string_sub (p
, "%P", conn
->connectpath
);
2387 string_sub (p
, "%S", lp_servicename (SNUM (conn
)));
2391 string_sub (p
, "%g", gidtoname (conn
->gid
));
2394 string_sub (p
, "%u", conn
->user
);
2397 /* Patch from jkf@soton.ac.uk Left the %N (NIS
2398 * server name) in standard_sub_basic as it is
2399 * a feature for logon servers, hence uses the
2400 * username. The %p (NIS server path) code is
2401 * here as it is used instead of the default
2402 * "path =" string in [homes] and so needs the
2403 * service name, not the username. */
2405 string_sub (p
, "%p", automount_path (lp_servicename (SNUM (conn
))));
2409 break; /* don't run off the end of the string
2418 standard_sub_basic (str
);
2423 /*******************************************************************
2424 are two IPs on the same subnet?
2425 ********************************************************************/
2427 same_net (struct in_addr ip1
, struct in_addr ip2
, struct in_addr mask
)
2429 uint32 net1
, net2
, nmask
;
2431 nmask
= ntohl (mask
.s_addr
);
2432 net1
= ntohl (ip1
.s_addr
);
2433 net2
= ntohl (ip2
.s_addr
);
2435 return ((net1
& nmask
) == (net2
& nmask
));
2439 /****************************************************************************
2440 a wrapper for gethostbyname() that tries with all lower and all upper case
2441 if the initial name fails
2442 ****************************************************************************/
2444 Get_Hostbyname (const char *name
)
2446 char *name2
= strdup (name
);
2447 struct hostent
*ret
;
2451 DEBUG (0, ("Memory allocation error in Get_Hostbyname! panic\n"));
2457 * This next test is redundent and causes some systems (with
2458 * broken isalnum() calls) problems.
2463 if (!isalnum (*name2
))
2470 ret
= sys_gethostbyname (name2
);
2477 /* try with all lowercase */
2479 ret
= sys_gethostbyname (name2
);
2486 /* try with all uppercase */
2488 ret
= sys_gethostbyname (name2
);
2495 /* nothing works :-( */
2501 /*******************************************************************
2502 turn a uid into a user name
2503 ********************************************************************/
2505 uidtoname (uid_t uid
)
2507 static char name
[40];
2508 struct passwd
*pass
= getpwuid (uid
);
2510 return (pass
->pw_name
);
2511 slprintf (name
, sizeof (name
) - 1, "%d", (int) uid
);
2516 /*******************************************************************
2517 turn a gid into a group name
2518 ********************************************************************/
2521 gidtoname (gid_t gid
)
2523 static char name
[40];
2524 struct group
*grp
= getgrgid (gid
);
2526 return (grp
->gr_name
);
2527 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
);
2771 /****************************************************************************
2772 routine to do file locking
2773 ****************************************************************************/
2775 fcntl_lock (int fd
, int op
, SMB_OFF_T offset
, SMB_OFF_T count
, int type
)
2777 #ifdef HAVE_FCNTL_LOCK
2778 SMB_STRUCT_FLOCK lock
;
2781 if (lp_ole_locking_compat ())
2783 SMB_OFF_T mask2
= ((SMB_OFF_T
) 0x3) << (SMB_OFF_T_BITS
- 4);
2784 SMB_OFF_T mask
= (mask2
<< 2);
2786 /* make sure the count is reasonable, we might kill the lockd otherwise */
2789 /* the offset is often strange - remove 2 of its bits if either of
2790 the top two bits are set. Shift the top ones by two bits. This
2791 still allows OLE2 apps to operate, but should stop lockd from
2793 if ((offset
& mask
) != 0)
2794 offset
= (offset
& ~mask
) | (((offset
& mask
) >> 2) & mask2
);
2798 SMB_OFF_T mask2
= ((SMB_OFF_T
) 0x4) << (SMB_OFF_T_BITS
- 4);
2799 SMB_OFF_T mask
= (mask2
<< 1);
2800 SMB_OFF_T neg_mask
= ~mask
;
2802 /* interpret negative counts as large numbers */
2806 /* no negative offsets */
2810 /* count + offset must be in range */
2811 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
2814 mask
= ((mask
>> 1) & neg_mask
);
2818 DEBUG (8, ("fcntl_lock %d %d %.0f %.0f %d\n", fd
, op
, (double) offset
, (double) count
, type
));
2821 lock
.l_whence
= SEEK_SET
;
2822 lock
.l_start
= offset
;
2828 ret
= fcntl (fd
, op
, &lock
);
2833 dbgtext ("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n",
2834 (double) offset
, (double) count
);
2835 dbgtext ("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
2837 ("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
2839 /* 32 bit NFS file system, retry with smaller offset */
2841 lock
.l_len
= count
& 0xffffffff;
2842 ret
= fcntl (fd
, op
, &lock
);
2846 DEBUG (3, ("fcntl lock gave errno %d (%s)\n", errno
, unix_error_string (errno
)));
2849 if (op
== SMB_F_GETLK
)
2852 (lock
.l_type
!= F_UNLCK
) && (lock
.l_pid
!= 0) && (lock
.l_pid
!= getpid ()))
2854 DEBUG (3, ("fd %d is locked by pid %d\n", fd
, (int) lock
.l_pid
));
2858 /* it must be not locked or locked by me */
2862 /* a lock set or unset */
2865 DEBUG (3, ("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2866 (double) offset
, (double) count
, op
, type
, unix_error_string (errno
)));
2868 /* perhaps it doesn't support this sort of locking?? */
2869 if (errno
== EINVAL
)
2871 DEBUG (3, ("locking not supported? returning True\n"));
2878 /* everything went OK */
2879 DEBUG (8, ("Lock call successful\n"));
2887 /*******************************************************************
2888 is the name specified one of my netbios names
2889 returns true is it is equal, false otherwise
2890 ********************************************************************/
2897 for (n
= 0; my_netbios_names
[n
]; n
++)
2899 if (strequal (my_netbios_names
[n
], s
))
2902 DEBUG (8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
2906 #if 0 /* Can be useful one day */
2907 /*******************************************************************
2908 set the horrid remote_arch string based on an enum.
2909 ********************************************************************/
2911 set_remote_arch (enum remote_arch_types type
)
2917 remote_arch
= "WfWg";
2920 remote_arch
= "OS2";
2923 remote_arch
= "Win95";
2926 remote_arch
= "WinNT";
2929 remote_arch
= "Samba";
2932 ra_type
= RA_UNKNOWN
;
2933 remote_arch
= "UNKNOWN";
2938 /*******************************************************************
2939 Get the remote_arch type.
2940 ********************************************************************/
2941 enum remote_arch_types
2942 get_remote_arch (void)
2948 /*******************************************************************
2949 align a pointer to a multiple of 2 bytes
2950 ********************************************************************/
2952 align2 (char *q
, char *base
)
2962 out_ascii (FILE * f
, unsigned char *buf
, int len
)
2965 for (i
= 0; i
< len
; i
++)
2967 fprintf (f
, "%c", isprint (buf
[i
]) ? buf
[i
] : '.');
2972 out_data (FILE * f
, char *buf1
, int len
, int per_line
)
2974 unsigned char *buf
= (unsigned char *) buf1
;
2981 fprintf (f
, "[%03X] ", i
);
2982 for (i
= 0; i
< len
;)
2984 fprintf (f
, "%02X ", (int) buf
[i
]);
2986 if (i
% (per_line
/ 2) == 0)
2988 if (i
% per_line
== 0)
2990 out_ascii (f
, &buf
[i
- per_line
], per_line
/ 2);
2992 out_ascii (f
, &buf
[i
- per_line
/ 2], per_line
/ 2);
2995 fprintf (f
, "[%03X] ", i
);
2998 if ((i
% per_line
) != 0)
3002 n
= per_line
- (i
% per_line
);
3004 if (n
> (per_line
/ 2))
3010 n
= MIN (per_line
/ 2, i
% per_line
);
3011 out_ascii (f
, &buf
[i
- (i
% per_line
)], n
);
3013 n
= (i
% per_line
) - n
;
3015 out_ascii (f
, &buf
[i
- n
], n
);
3022 print_asc (int level
, unsigned char *buf
, int len
)
3025 for (i
= 0; i
< len
; i
++)
3026 DEBUG (level
, ("%c", isprint (buf
[i
]) ? buf
[i
] : '.'));
3030 dump_data (int level
, char *buf1
, int len
)
3032 unsigned char *buf
= (unsigned char *) buf1
;
3037 DEBUG (level
, ("[%03X] ", i
));
3038 for (i
= 0; i
< len
;)
3040 DEBUG (level
, ("%02X ", (int) buf
[i
]));
3043 DEBUG (level
, (" "));
3046 print_asc (level
, &buf
[i
- 16], 8);
3047 DEBUG (level
, (" "));
3048 print_asc (level
, &buf
[i
- 8], 8);
3049 DEBUG (level
, ("\n"));
3051 DEBUG (level
, ("[%03X] ", i
));
3059 DEBUG (level
, (" "));
3061 DEBUG (level
, (" "));
3063 DEBUG (level
, (" "));
3065 n
= MIN (8, i
% 16);
3066 print_asc (level
, &buf
[i
- (i
% 16)], n
);
3067 DEBUG (level
, (" "));
3070 print_asc (level
, &buf
[i
- n
], n
);
3071 DEBUG (level
, ("\n"));
3075 /*****************************************************************************
3076 * Provide a checksum on a string
3078 * Input: s - the null-terminated character string for which the checksum
3079 * will be calculated.
3081 * Output: The checksum value calculated for s.
3083 * ****************************************************************************
3086 str_checksum (const char *s
)
3095 res
^= (c
<< (i
% 15)) ^ (c
>> (15 - (i
% 15)));
3100 } /* str_checksum */
3105 /*****************************************************************
3106 zero a memory area then free it. Used to catch bugs faster
3107 *****************************************************************/
3109 zero_free (void *p
, size_t size
)
3111 memset (p
, 0, size
);
3116 /*****************************************************************
3117 set our open file limit to a requested max and return the limit
3118 *****************************************************************/
3120 set_maxfiles (int requested_max
)
3122 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
3124 int saved_current_limit
;
3126 if (getrlimit (RLIMIT_NOFILE
, &rlp
))
3128 DEBUG (0, ("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
3129 unix_error_string (errno
)));
3131 return requested_max
;
3135 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
3136 * account for the extra fd we need
3137 * as well as the log files and standard
3138 * handles etc. Save the limit we want to set in case
3139 * we are running on an OS that doesn't support this limit (AIX)
3140 * which always returns RLIM_INFINITY for rlp.rlim_max.
3143 saved_current_limit
= rlp
.rlim_cur
= MIN (requested_max
, rlp
.rlim_max
);
3145 if (setrlimit (RLIMIT_NOFILE
, &rlp
))
3147 DEBUG (0, ("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
3148 (int) rlp
.rlim_cur
, unix_error_string (errno
)));
3150 return saved_current_limit
;
3153 if (getrlimit (RLIMIT_NOFILE
, &rlp
))
3155 DEBUG (0, ("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
3156 unix_error_string (errno
)));
3158 return saved_current_limit
;
3161 #if defined(RLIM_INFINITY)
3162 if (rlp
.rlim_cur
== RLIM_INFINITY
)
3163 return saved_current_limit
;
3166 if ((int) rlp
.rlim_cur
> saved_current_limit
)
3167 return saved_current_limit
;
3169 return rlp
.rlim_cur
;
3170 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
3172 * No way to know - just guess...
3174 return requested_max
;