mirror of
https://github.com/samba-team/samba.git
synced 2025-01-24 02:04:21 +03:00
Added "inherit permissions" patch.
Fixed locking bug found by Andrew. Jeremy. (This used to be commit 38dffd360dc2e44bfc9e751f017e24f81ff0f2fa)
This commit is contained in:
parent
2afd5d5eb5
commit
3a6c2069d7
@ -347,6 +347,7 @@ char *smbd_mktemp(char *template);
|
||||
void *memdup(void *p, size_t size);
|
||||
char *myhostname(void);
|
||||
char *lock_path(char *name);
|
||||
char *parent_dirname(const char *path);
|
||||
|
||||
/*The following definitions come from lib/util_array.c */
|
||||
|
||||
@ -1336,6 +1337,7 @@ BOOL lp_dos_filetimes(int );
|
||||
BOOL lp_dos_filetime_resolution(int );
|
||||
BOOL lp_fake_dir_create_times(int );
|
||||
BOOL lp_blocking_locks(int );
|
||||
BOOL lp_inherit_perms(int );
|
||||
int lp_create_mask(int );
|
||||
int lp_force_create_mode(int );
|
||||
int _lp_security_mask(int );
|
||||
@ -2612,7 +2614,7 @@ void DirCacheFlush(int snum);
|
||||
|
||||
/*The following definitions come from smbd/dosmode.c */
|
||||
|
||||
mode_t unix_mode(connection_struct *conn,int dosmode);
|
||||
mode_t unix_mode(connection_struct *conn,int dosmode,const 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);
|
||||
|
@ -39,6 +39,9 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
|
||||
#ifndef SIOCGIFCONF
|
||||
|
@ -3280,3 +3280,31 @@ char *lock_path(char *name)
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
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.
|
||||
********************************************************************/
|
||||
|
||||
char *parent_dirname(const char *path)
|
||||
{
|
||||
static pstring dirpath;
|
||||
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;
|
||||
}
|
||||
|
@ -357,6 +357,7 @@ typedef struct
|
||||
BOOL bDosFiletimeResolution;
|
||||
BOOL bFakeDirCreateTimes;
|
||||
BOOL bBlockingLocks;
|
||||
BOOL bInheritPerms;
|
||||
char dummy[3]; /* for alignment */
|
||||
} service;
|
||||
|
||||
@ -462,6 +463,7 @@ static service sDefault =
|
||||
False, /* bDosFiletimeResolution */
|
||||
False, /* bFakeDirCreateTimes */
|
||||
True, /* bBlockingLocks */
|
||||
False, /* bInheritPerms */
|
||||
"" /* dummy */
|
||||
};
|
||||
|
||||
@ -609,6 +611,7 @@ static struct parm_struct parm_table[] =
|
||||
{"force directory mode", P_OCTAL,P_LOCAL,&sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
|
||||
{"directory security mask",P_OCTAL,P_LOCAL,&sDefault.iDir_Security_mask,NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
|
||||
{"force directory security mode",P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode,NULL,NULL,FLAG_GLOBAL|FLAG_SHARE},
|
||||
{"inherit permissions",P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
|
||||
{"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
|
||||
{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
|
||||
{"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
|
||||
@ -1397,6 +1400,7 @@ FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
|
||||
FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
|
||||
FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
|
||||
FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
|
||||
FN_LOCAL_BOOL(lp_inherit_perms,bInheritPerms)
|
||||
|
||||
FN_LOCAL_INTEGER(lp_create_mask,iCreate_mask)
|
||||
FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
|
||||
|
@ -208,7 +208,13 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec
|
||||
* of smb_lkrng structs.
|
||||
*/
|
||||
|
||||
for(i = blr->lock_num; i >= 0; i--) {
|
||||
/*
|
||||
* Ensure we don't do a remove on the lock that just failed,
|
||||
* as under POSIX rules, if we have a lock already there, we
|
||||
* will delete it (and we shouldn't) .....
|
||||
*/
|
||||
|
||||
for(i = blr->lock_num - 1; i >= 0; i--) {
|
||||
int dummy1;
|
||||
uint32 dummy2;
|
||||
BOOL err;
|
||||
|
@ -26,33 +26,68 @@ extern int DEBUGLEVEL;
|
||||
/****************************************************************************
|
||||
change a dos mode to a unix mode
|
||||
base permission for files:
|
||||
everybody gets read bit set
|
||||
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
|
||||
Then apply create mask,
|
||||
then add force bits.
|
||||
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
|
||||
Then apply create mask,
|
||||
then add force bits.
|
||||
if !inheriting {
|
||||
Then apply create mask,
|
||||
then add force bits.
|
||||
}
|
||||
****************************************************************************/
|
||||
mode_t unix_mode(connection_struct *conn,int dosmode)
|
||||
mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
|
||||
{
|
||||
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
|
||||
mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
|
||||
|
||||
if ( !IS_DOS_READONLY(dosmode) )
|
||||
result |= (S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
|
||||
|
||||
if (fname && lp_inherit_perms(SNUM(conn))) {
|
||||
char *dname;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
|
||||
dname = parent_dirname(fname);
|
||||
DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
|
||||
if (dos_stat(dname,&sbuf) != 0) {
|
||||
DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
|
||||
return(0); /* *** shouldn't happen! *** */
|
||||
}
|
||||
|
||||
/* Save for later - but explicitly remove setuid bit for safety. */
|
||||
dir_mode = sbuf.st_mode & ~S_ISUID;
|
||||
DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)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_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
|
||||
/* Apply directory mask */
|
||||
result &= lp_dir_mask(SNUM(conn));
|
||||
/* Add in force bits */
|
||||
result |= lp_force_dir_mode(SNUM(conn));
|
||||
result |= (S_IFDIR | S_IWUSR);
|
||||
|
||||
if (dir_mode) {
|
||||
/* 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_mask(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;
|
||||
@ -62,11 +97,17 @@ mode_t unix_mode(connection_struct *conn,int dosmode)
|
||||
|
||||
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
|
||||
result |= S_IXOTH;
|
||||
|
||||
/* Apply mode mask */
|
||||
result &= lp_create_mask(SNUM(conn));
|
||||
/* Add in force bits */
|
||||
result |= lp_force_create_mode(SNUM(conn));
|
||||
|
||||
if (dir_mode) {
|
||||
/* 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_mask(SNUM(conn));
|
||||
/* Add in force bits */
|
||||
result |= lp_force_create_mode(SNUM(conn));
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
@ -155,7 +196,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *
|
||||
|
||||
if (dos_mode(conn,fname,st) == dosmode) return(0);
|
||||
|
||||
unixmode = unix_mode(conn,dosmode);
|
||||
unixmode = unix_mode(conn,dosmode,fname);
|
||||
|
||||
/* preserve the s bits */
|
||||
mask |= (S_ISUID | S_ISGID);
|
||||
|
@ -726,7 +726,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,smb_attr | aARCH);
|
||||
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
||||
|
||||
/*
|
||||
* If it's a request for a directory open, deal with it separately.
|
||||
@ -1073,7 +1073,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,smb_attr | aARCH);
|
||||
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
||||
|
||||
/*
|
||||
* If it's a request for a directory open, deal with it separately.
|
||||
@ -1834,7 +1834,7 @@ static size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
|
||||
* 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);
|
||||
mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name);
|
||||
|
||||
owner_access = map_unix_perms(&owner_acl_type, mode,
|
||||
S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
|
||||
|
@ -1147,7 +1147,7 @@ int open_directory(files_struct *fsp,connection_struct *conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(dos_mkdir(fname, unix_mode(conn,aDIR)) < 0) {
|
||||
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;
|
||||
|
@ -1547,7 +1547,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,aARCH);
|
||||
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);
|
||||
@ -1649,7 +1649,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,smb_attr | aARCH);
|
||||
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
||||
|
||||
open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
|
||||
oplock_request, &rmode,&smb_action);
|
||||
@ -1773,7 +1773,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,createmode);
|
||||
unixmode = unix_mode(conn,createmode,fname);
|
||||
|
||||
fsp = file_new();
|
||||
if (!fsp)
|
||||
@ -1853,7 +1853,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
pstrcat(fname,"/TMXXXXXX");
|
||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
||||
|
||||
unixmode = unix_mode(conn,createmode);
|
||||
unixmode = unix_mode(conn,createmode,fname);
|
||||
|
||||
fsp = file_new();
|
||||
if (fsp)
|
||||
@ -3076,7 +3076,7 @@ int reply_printopen(connection_struct *conn,
|
||||
|
||||
/* 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);
|
||||
(FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unix_mode(conn,0,fname2), 0, NULL, NULL);
|
||||
|
||||
if (!fsp->open) {
|
||||
file_free(fsp);
|
||||
@ -3235,7 +3235,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
unix_convert(directory,conn,0,&bad_path,NULL);
|
||||
|
||||
if (check_name(directory, conn))
|
||||
ret = dos_mkdir(directory,unix_mode(conn,aDIR));
|
||||
ret = dos_mkdir(directory,unix_mode(conn,aDIR,directory));
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -4291,7 +4291,12 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
|
||||
/* If any of the above locks failed, then we must unlock
|
||||
all of the previous locks (X/Open spec). */
|
||||
if(i != num_locks && num_locks != 0) {
|
||||
for(; i >= 0; i--) {
|
||||
/*
|
||||
* Ensure we don't do a remove on the lock that just failed,
|
||||
* as under POSIX rules, if we have a lock already there, we
|
||||
* will delete it (and we shouldn't) .....
|
||||
*/
|
||||
for(i--; i >= 0; i--) {
|
||||
count = get_lock_count( data, i, large_file_format, &err1);
|
||||
offset = get_lock_offset( data, i, large_file_format, &err2);
|
||||
|
||||
|
@ -232,7 +232,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,open_attr | aARCH);
|
||||
unixmode = unix_mode(conn,open_attr | aARCH, fname);
|
||||
|
||||
open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
|
||||
oplock_request, &rmode,&smb_action);
|
||||
@ -2014,7 +2014,7 @@ static int call_trans2mkdir(connection_struct *conn,
|
||||
|
||||
unix_convert(directory,conn,0,&bad_path,NULL);
|
||||
if (check_name(directory,conn))
|
||||
ret = dos_mkdir(directory,unix_mode(conn,aDIR));
|
||||
ret = dos_mkdir(directory,unix_mode(conn,aDIR,directory));
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user