On Fri, 2 Jul 1999, Jeremy Allison wrote:
> T.D.Lee@durham.ac.uk wrote:
> >
> >
> > But we'd like to go one step further and have the return code from
preexec
> > be used to continue or abort the connection being established. The
script
> > above would be modified to generate this return code.
> >
> > Looking through the source code (smbd/service.c), it doesn't seem
to check
> > the return code (calling smbrun to do the preexec).
> >
> > Is there any reason for this apparent oversight? Or is it a bug?
> > Should I try to adjust the source code and submit a patch?
>
> That sounds like a good idea. The only thing you'll have to
> make sure is that by default the code doesn't care about
> preexec returns as that's the way most people will have
> written their scripts right now.
>
> You'll need a new option to turn on your modified behaviour.
Many thanks for your reply, which I appreciate. My apologies for not
replying much sooner: we had two weeks holiday, and then two weeks frantic
activity here at work, which will continue but (hopefully!) easing off
slightly.
I hope to try to do this preexec idea in the next few weeks (and I take
your point about existing behaviour and assumptions).
Some different enhancements:
1. The "inherit mode" idea I implemented a few months ago: though I
submitted this idea to the samba team at the time, I have heard nothing
officially from you. This idea is vital to our work here, with some
15,000 users. Please could you cast your eye over the attached description
and patch, and incorporate it (or if you think it is a bad idea, let me
know why).
2. quotas: The "--with-quotas" is important to us, and it works
nicely
under Solaris 2.6 . But our latest fileserver, also Solaris 2.6, uses
Veritas VxFS filesystem (instead of native Solaris ufs) and quotas don't
work. Any ideas? I am chasing Sun and Veritas about the programmatic
interface to VxFS quotas. Assuming they tell me this (and I'll push
hard!) I will be happy to try to get Veritas quotas working for Samba and
contribute this to you.
Enclosed:
"inherit mode": brief description
"inherit mode": patch
--
: David Lee I.T. Service :
: Systems Programmer Computer Centre :
: University of Durham :
: Phone: +44 191 374 2882 (ddi) South Road :
: Fax: +44 191 374 7759 Durham :
: Internet: T.D.Lee@durham.ac.uk U.K. :
-------------- next part --------------
File ownerships and permissions in SAMBA 2.x
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SAMBA is a very useful product for serving files to the PC desktop
from a UNIX filserver.
But in a large environment (thousands of identifiers and groups) its
filesharing abilities are insufficiently flexible. While much of this is
inherent in the SMB protocol, nevertheless more could be done. This paper
suggests some extensions.
Disclaimer
~~~~~~~~~~
My knowledge of PCs is miniscule, and my knowledge of SMB even smaller.
So there may well be detailed inaccuracies in this paper. Please
read it, in the first instance, for the principles.
Starting point
~~~~~~~~~~~~~~
A large system, many thousand users, many hundred UNIX groups.
Privacy of data is important. The default umask will be something like 077
rather than 022. But user-controlled filesharing is also important, using
UNIX permissions and UNIX groups.
Desktop primarily PC, but some UNIX.
Integrated PC/UNIX filestore, particularly a "home directory" per
user.
Any solution must be general, with relatively little done centrally,
relatively much devolved to user. For example "smb.conf(5)" has a
simple
"[homes]" share, covering all users; little more than a default
configuration.
It is grossly impractical to be tailoring the generic smb.conf (a centralised
item) with per-user information. Besides, that would be insufficient for
general filesharing amongst consenting users which requires even finer-grained
per-directory control.
The problem
~~~~~~~~~~~
A user carefully sets permissions on a particular file (and its ancestor
directories) to allow sharing to a specified group. Using a typical Windows
application (WORD, Excel) to edit that file results in obliteration of those
owner/mode details. This is a "fact of life" with such applications.
A partial solution is to open up the default umask from 077 (private) to
something like 027 (group access) and use the UNIX "g+s" semantics on
the
directory. But this is a global sledgehammer solution to a problem that
requires much finer-grained control, at least per-user and preferably
per-directory or even per-file.
Because of the way Windows applications work, I think we have to accept that
per-file control is unrealistic. But per-directory control would still be
very beneficial.
The proposal
~~~~~~~~~~~~
It is proposed to extend samba in an upwards compatible manner to allow
per-user and per-directory setting of owner/mode information on directories
and thence to files in these directories.
UNIX aficionados will be aware of mechanisms such as .login and .profile
to allow users to tailor their working environment, such as umask settings.
They may also be aware of analogous mechanisms on a per-directory level
(such as ".nsr" used by the Legato NetWorker backup product).
It is suggested that samba recognise and act on such a file to allow
user-controlled owner/mode tailoring. Its processing and interpretation
would be modelled after the existing smb.conf "include
.../%u/.../<file>".
This is hereinafter called the "dirinclude" file: the reasons will
become
apparent. Such a file may be placed in any directory within a
"[homes]"
share. It might be more generally useful, but I have not explored that.
The file contains a subset of "smb.conf" instructions, such as:
create mask (and create mode)
directory mask (and directory mode)
force create mode (and force directory mode)
force group
Other instructions may well be useful:
delete readonly
dont descend
dos filetime resolution
oplocks
The above lists are by no means exhaustive.
Backwards-compatibility principles probably require the default to be
"off".
It is suggested that the main "smb.conf" file contain a global switch
for this feature, such as "dirinclude <filename-template>".
When given,
it switches on this feature. In each directory it looks for a filename
matching the template (e.g. "samba.smb") and, if found, processes it.
The effects in one directory are inherited by all subdirectories, but can
be further modified by such files in those subdirectories.
Caveats
~~~~~~~
Creation of, change to, and deletion of, the "dirinclude" files need
to be
detected and acted upon. Detection is very easy and painless: a UNIX
"stat"
is done by the "smbd" daemon on the "dirinclude" files
themselves prior to
doing a significant operation. Each stat result is cached: if it has changed
(and 99.9% of the time it won't) then the file can be reprocessed.
David Lee
T.D.Lee@durham.ac.uk
March 1999
-------------- next part --------------
*** docs/yodldocs/smb.conf.5.yo.orig Sat May 15 02:20:48 1999
--- docs/yodldocs/smb.conf.5.yo Thu May 20 10:07:58 1999
***************
*** 859,864 ****
--- 859,866 ----
it() link(bf(include))(include)
+ it() link(bf(inherit mode))(inheritmode)
+
it() link(bf(invalid users))(invalidusers)
it() link(bf(locking))(locking)
***************
*** 2486,2491 ****
--- 2488,2526 ----
It takes the standard substitutions, except link(bf(%u))(percentu),
link(bf(%P))(percentP) and link(bf(%S))(percentS).
+ label(inheritmode)
+ dit(bf(inherit mode (S)))
+
+ The permissions on new files and directories are normally governed by
+ link(bf("create mask"))(createmask),
+ link(bf("directory mask"))(directorymask),
+ link(bf("force create mode"))(forcecreatemode) and
+ link(bf("force directory mode"))(forcedirectorymode)
+ but inherit mode overrides this.
+
+ New directories inherit the mode of the parent directory,
+ including bits such as setgid.
+
+ New files inherit their read/write bits from the parent directory.
+ Their execute bits continue to be determined by
+ link(bf("map archive"))(maparchive),
+ link(bf("map hidden"))(maphidden) and
+ link(bf("map system"))(mapsystem) as usual.
+
+ This can be particularly useful on large systems with many users,
+ perhaps several thousand,
+ to allow a single bf([homes]) share to be used flexibly by each user.
+
+ See the separate tt(INHERIT_MODE.txt) document.
+
+ See also link(bf("create mask"))(createmask) etc.
+
+ bf(Default)
+ tt( inherit mode = no)
+
+ bf(Example)
+ tt( inherit mode = yes)
+
label(interfaces)
dit(bf(interfaces (G)))
*** source/include/proto.h.orig Tue May 18 00:27:59 1999
--- source/include/proto.h Tue May 18 16:09:34 1999
***************
*** 1150,1155 ****
--- 1150,1156 ----
BOOL lp_fake_dir_create_times(int );
BOOL lp_blocking_locks(int );
BOOL lp_mangle_locks(int );
+ BOOL lp_inherit_mode(int );
int lp_create_mode(int );
int lp_force_create_mode(int );
int lp_dir_mode(int );
***************
*** 2364,2370 ****
/*The following definitions come from smbd/dosmode.c */
! mode_t unix_mode(connection_struct *conn,int dosmode);
int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf);
int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT
*st);
int file_utime(connection_struct *conn, char *fname, struct utimbuf *times);
--- 2365,2371 ----
/*The following definitions come from smbd/dosmode.c */
! mode_t unix_mode(connection_struct *conn,int dosmode,char *fname);
int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf);
int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT
*st);
int file_utime(connection_struct *conn, char *fname, struct utimbuf *times);
*** source/param/loadparm.c.orig Tue May 18 00:37:43 1999
--- source/param/loadparm.c Tue May 18 16:09:35 1999
***************
*** 339,345 ****
BOOL bFakeDirCreateTimes;
BOOL bBlockingLocks;
BOOL bMangleLocks;
! char dummy[3]; /* for alignment */
} service;
--- 339,346 ----
BOOL bFakeDirCreateTimes;
BOOL bBlockingLocks;
BOOL bMangleLocks;
! BOOL bInheritMode;
! char dummy[2]; /* for alignment */
} service;
***************
*** 434,439 ****
--- 435,441 ----
False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
True, /* bMangleLocks */
+ False, /* bInheritMode */
"" /* dummy */
};
***************
*** 740,745 ****
--- 742,748 ----
{"Locking Options", P_SEP, P_SEPARATOR},
{"blocking locks", P_BOOL, P_LOCAL,
&sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"inherit mode", P_BOOL, P_LOCAL,
&sDefault.bInheritMode, NULL, NULL, FLAG_SHARE},
{"fake oplocks", P_BOOL, P_LOCAL,
&sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
{"kernel oplocks", P_BOOL, P_GLOBAL,
&Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
{"locking", P_BOOL, P_LOCAL, &sDefault.bLocking,
NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
***************
*** 1334,1339 ****
--- 1337,1343 ----
FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
FN_LOCAL_BOOL(lp_mangle_locks,bMangleLocks)
+ FN_LOCAL_BOOL(lp_inherit_mode,bInheritMode)
FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
*** source/smbd/dosmode.c.orig Sat Feb 27 22:09:09 1999
--- source/smbd/dosmode.c Tue May 18 16:09:36 1999
***************
*** 23,58 ****
extern int DEBUGLEVEL;
/****************************************************************************
change a dos mode to a unix mode
base permission for files:
! everybody gets read bit set
dos readonly is represented in unix by removing everyone's write
bit
dos archive is represented in unix by the user's execute bit
dos system is represented in unix by the group's execute bit
dos hidden is represented in unix by the other's execute bit
! Then apply create mask,
! then add force bits.
base permission for directories:
dos directory is represented in unix by unix's dir bit and the
exec bit
! Then apply create mask,
! then add force bits.
****************************************************************************/
! mode_t unix_mode(connection_struct *conn,int dosmode)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
if ( !IS_DOS_READONLY(dosmode) )
result |= (S_IWUSR | S_IWGRP | S_IWOTH);
if (IS_DOS_DIR(dosmode)) {
/* We never make directories read only for the owner as under DOS a user
can always create a file in a read-only directory. */
! result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
! /* Apply directory mask */
! result &= lp_dir_mode(SNUM(conn));
! /* Add in force bits */
! result |= lp_force_dir_mode(SNUM(conn));
} else {
if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
result |= S_IXUSR;
--- 23,122 ----
extern int DEBUGLEVEL;
+ /*******************************************************************
+ Given a filename - get its directory name
+ NB: Returned in static storage. Caveats:
+ o Not safe in thread environment.
+ o Caller must not free.
+ o If caller wishes to preserve, they should copy.
+ *******************************************************************/
+ /*******************************************************************
+ This should probably be elsewhere, and more generally available.
+ *******************************************************************/
+ static char *parent_dirname(char *path)
+ {
+ static char dirpath[MAXPATHLEN + 1];
+ char *p;
+
+ if (!path) return(NULL);
+
+ pstrcpy(dirpath, path);
+ p = strrchr(dirpath, '/'); /* Find final '/', if any */
+ if (!p) {
+ pstrcpy(dirpath, "."); /* No final "/", so dir is
"." */
+ }
+ else {
+ if (p == dirpath) ++p; /* For root "/", leave "/" in
place */
+ *p = '\0';
+ }
+ return(dirpath);
+ }
+
/****************************************************************************
change a dos mode to a unix mode
base permission for files:
! if inheriting
! apply read/write bits from parent directory.
! else
! everybody gets read bit set
dos readonly is represented in unix by removing everyone's write
bit
dos archive is represented in unix by the user's execute bit
dos system is represented in unix by the group's execute bit
dos hidden is represented in unix by the other's execute bit
! if !inheriting {
! Then apply create mask,
! then add force bits.
! }
base permission for directories:
dos directory is represented in unix by unix's dir bit and the
exec bit
! if !inheriting {
! Then apply create mask,
! then add force bits.
! }
****************************************************************************/
! mode_t unix_mode(connection_struct *conn,int dosmode,char *fname)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
+ mode_t dir_mode;
if ( !IS_DOS_READONLY(dosmode) )
result |= (S_IWUSR | S_IWGRP | S_IWOTH);
+
+ if (lp_inherit_mode(SNUM(conn))) {
+ char *dname;
+ SMB_STRUCT_STAT sbuf;
+
+ dname = parent_dirname(dos_to_unix(fname, False));
+ DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
+ if (sys_stat(dname,&sbuf) != 0) {
+ DEBUG(4,("unix_mode(%s) failed, [dir %s]:
%s\n",fname,dname,strerror(errno)));
+ return(0); /* *** shouldn't happen! *** */
+ }
+ /* Save 777 part for later */
+ /* dir_mode = sbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); */
+ /* Save for later */
+ dir_mode = sbuf.st_mode;
+ DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,dir_mode));
+ /* Clear "result" */
+ result = 0;
+ }
if (IS_DOS_DIR(dosmode)) {
/* We never make directories read only for the owner as under DOS a user
can always create a file in a read-only directory. */
! result |= (S_IFDIR | S_IWUSR);
!
! if (lp_inherit_mode(SNUM(conn))) {
! /* Inherit mode of parent directory */
! result |= dir_mode;
! } else {
! /* Provisionally add all 'x' bits */
! result |= (S_IXUSR | S_IXGRP | S_IXOTH);
! /* Apply directory mask */
! result &= lp_dir_mode(SNUM(conn));
! /* Add in force bits */
! result |= lp_force_dir_mode(SNUM(conn));
! }
} else {
if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
result |= S_IXUSR;
***************
*** 63,72 ****
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
result |= S_IXOTH;
! /* Apply mode mask */
! result &= lp_create_mode(SNUM(conn));
! /* Add in force bits */
! result |= lp_force_create_mode(SNUM(conn));
}
return(result);
}
--- 127,142 ----
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
result |= S_IXOTH;
! if (lp_inherit_mode(SNUM(conn))) {
! /* Inherit 666 component of parent directory mode */
! result |= dir_mode
! & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
! } else {
! /* Apply mode mask */
! result &= lp_create_mode(SNUM(conn));
! /* Add in force bits */
! result |= lp_force_create_mode(SNUM(conn));
! }
}
return(result);
}
***************
*** 155,161 ****
if (dos_mode(conn,fname,st) == dosmode) return(0);
! unixmode = unix_mode(conn,dosmode);
/* preserve the s bits */
mask |= (S_ISUID | S_ISGID);
--- 225,231 ----
if (dos_mode(conn,fname,st) == dosmode) return(0);
! unixmode = unix_mode(conn,dosmode,fname);
/* preserve the s bits */
mask |= (S_ISUID | S_ISGID);
*** source/smbd/nttrans.c.orig Sat May 15 02:06:39 1999
--- source/smbd/nttrans.c Wed May 19 15:30:43 1999
***************
*** 722,728 ****
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,smb_attr | aARCH);
/*
* If it's a request for a directory open, deal with it separately.
--- 722,728 ----
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,smb_attr | aARCH, fname);
/*
* If it's a request for a directory open, deal with it separately.
***************
*** 1061,1067 ****
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,smb_attr | aARCH);
/*
* If it's a request for a directory open, deal with it separately.
--- 1061,1067 ----
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,smb_attr | aARCH, fname);
/*
* If it's a request for a directory open, deal with it separately.
***************
*** 1715,1720 ****
--- 1715,1721 ----
SEC_ACCESS other_access;
int other_acl_type;
int num_acls = 0;
+ pstring fname;
*ppdesc = NULL;
***************
*** 1771,1777 ****
* ACE entries. These are the permissions a file would get when
* being created in the directory.
*/
! mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE);
owner_access = map_unix_perms(&owner_acl_type, mode,
S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
--- 1772,1785 ----
* ACE entries. These are the permissions a file would get when
* being created in the directory.
*/
! mode_t mode;
! /*
! * For fname arg to unix_mode(), use dirname with trailing "/" so
that,
! * under "inherit mode", it uses this directory rather than parent.
! */
! pstrcpy(fname, fsp->fsp_name);
! pstrcat(fname, "/");
! mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fname);
owner_access = map_unix_perms(&owner_acl_type, mode,
S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
*** source/smbd/open.c.orig Sat May 15 02:06:39 1999
--- source/smbd/open.c Tue May 18 16:09:37 1999
***************
*** 1136,1142 ****
* Create the directory.
*/
! if(dos_mkdir(fname, unix_mode(conn,aDIR)) < 0) {
DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
return -1;
--- 1136,1142 ----
* Create the directory.
*/
! if(dos_mkdir(fname, unix_mode(conn,aDIR,fname)) < 0) {
DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
return -1;
*** source/smbd/reply.c.orig Sat May 15 02:06:40 1999
--- source/smbd/reply.c Tue May 18 16:09:38 1999
***************
*** 1459,1465 ****
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,aARCH);
open_file_shared(fsp,conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
unixmode, oplock_request,&rmode,NULL);
--- 1459,1465 ----
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,aARCH,fname);
open_file_shared(fsp,conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
unixmode, oplock_request,&rmode,NULL);
***************
*** 1561,1567 ****
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,smb_attr | aARCH);
open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
oplock_request, &rmode,&smb_action);
--- 1561,1567 ----
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,smb_attr | aARCH, fname);
open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
oplock_request, &rmode,&smb_action);
***************
*** 1685,1691 ****
DEBUG(0,("Attempt to create file (%s) with volid set - please
report this\n",fname));
}
! unixmode = unix_mode(conn,createmode);
fsp = file_new();
if (!fsp)
--- 1685,1691 ----
DEBUG(0,("Attempt to create file (%s) with volid set - please
report this\n",fname));
}
! unixmode = unix_mode(conn,createmode,fname);
fsp = file_new();
if (!fsp)
***************
*** 1765,1771 ****
pstrcat(fname,"/TMXXXXXX");
unix_convert(fname,conn,0,&bad_path,NULL);
! unixmode = unix_mode(conn,createmode);
fsp = file_new();
if (fsp)
--- 1765,1771 ----
pstrcat(fname,"/TMXXXXXX");
unix_convert(fname,conn,0,&bad_path,NULL);
! unixmode = unix_mode(conn,createmode,fname);
fsp = file_new();
if (fsp)
***************
*** 2986,2992 ****
/* Open for exclusive use, write only. */
open_file_shared(fsp,conn,fname2,
SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
! (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL),
unix_mode(conn,0), 0, NULL, NULL);
if (!fsp->open) {
file_free(fsp);
--- 2986,2992 ----
/* Open for exclusive use, write only. */
open_file_shared(fsp,conn,fname2,
SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
! (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL),
unix_mode(conn,0,fname2), 0, NULL, NULL);
if (!fsp->open) {
file_free(fsp);
***************
*** 3145,3151 ****
unix_convert(directory,conn,0,&bad_path,NULL);
if (check_name(directory, conn))
! ret = dos_mkdir(directory,unix_mode(conn,aDIR));
if (ret < 0)
{
--- 3145,3151 ----
unix_convert(directory,conn,0,&bad_path,NULL);
if (check_name(directory, conn))
! ret = dos_mkdir(directory,unix_mode(conn,aDIR,directory));
if (ret < 0)
{
*** source/smbd/trans2.c.orig Sat May 15 02:06:40 1999
--- source/smbd/trans2.c Tue May 18 16:09:38 1999
***************
*** 232,238 ****
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,open_attr | aARCH);
open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
oplock_request, &rmode,&smb_action);
--- 232,238 ----
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
! unixmode = unix_mode(conn,open_attr | aARCH, fname);
open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
oplock_request, &rmode,&smb_action);
***************
*** 1962,1968 ****
unix_convert(directory,conn,0,&bad_path,NULL);
if (check_name(directory,conn))
! ret = dos_mkdir(directory,unix_mode(conn,aDIR));
if(ret < 0)
{
--- 1962,1968 ----
unix_convert(directory,conn,0,&bad_path,NULL);
if (check_name(directory,conn))
! ret = dos_mkdir(directory,unix_mode(conn,aDIR,directory));
if(ret < 0)
{