1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

Cause smbd to use the new posix_acls code, not the old unix_acls code.

Currently does exactly the same thing (returns ACLs the same way). This
code is written to try and get a POSIX ACL via the abstract sys_XX interface,
then fall back to providing a UNIX based ACL if the calls fail. Seems to
work. Next step is to add a --with-posix-acls to configure.in and then
check on a POSIX ACL system that a complex ACL is returned correctly
as an NT ACL. Note that the ACL set (a more complex problem) is not
addressed yet.
Jeremy.
This commit is contained in:
Jeremy Allison 0001-01-01 00:00:00 +00:00
parent 3d0ecea18d
commit 4339e20202
8 changed files with 98 additions and 75 deletions

View File

@ -104,7 +104,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/crc32.o lib/snprintf.o lib/wins_srv.o \
lib/util_array.o lib/util_str.o lib/util_sid.o \
lib/util_unistr.o lib/util_file.o \
lib/util_unistr.o lib/util_file.o lib/sysacls.o \
lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \
lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \
@ -179,7 +179,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
smbd/blocking.o smbd/sec_ctx.o \
smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
smbd/unix_acls.o lib/msrpc-client.o lib/msrpc_use.o \
smbd/posix_acls.o lib/msrpc-client.o lib/msrpc_use.o \
smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/util_seaccess.o

View File

@ -240,6 +240,23 @@ void standard_sub_snum(int snum, char *str);
void standard_sub_vuser(char *str, user_struct *vuser);
void standard_sub_vsnum(char *str, user_struct *vuser, int snum);
/*The following definitions come from lib/sysacls.c */
int sys_acl_get_entry( SMB_ACL_T acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d);
SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type);
SMB_ACL_T sys_acl_get_fd(int fd);
int sys_acl_free( void *obj_p);
int sys_acl_get_entry( SMB_ACL_T acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d);
SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type);
SMB_ACL_T sys_acl_get_fd(int fd);
int sys_acl_free( void *obj_p);
/*The following definitions come from lib/system.c */
int sys_usleep(long usecs);
@ -1731,10 +1748,10 @@ BOOL pdb_delete_sam_account (char* username);
BOOL pdb_setsampwent(BOOL update);
void pdb_endsampwent(void);
SAM_ACCOUNT* pdb_getsampwent(void);
SAM_ACCOUNT* pdb_getsampwnam (char *name);
SAM_ACCOUNT* pdb_getsampwnam (char *sname);
SAM_ACCOUNT* pdb_getsampwuid (uid_t uid);
SAM_ACCOUNT* pdb_getsampwrid (uint32 rid);
BOOL pdb_delete_sam_account(char *name);
BOOL pdb_delete_sam_account(char *sname);
BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override);
BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd);
@ -3699,6 +3716,13 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf);
#endif
/*The following definitions come from smbd/posix_acls.c */
#if OLD_NTDOMAIN
size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc);
BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd);
#endif
/*The following definitions come from smbd/process.c */
#if OLD_NTDOMAIN
@ -3866,13 +3890,6 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype);
BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype);
#endif
/*The following definitions come from smbd/unix_acls.c */
#if OLD_NTDOMAIN
size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc);
BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd);
#endif
/*The following definitions come from smbd/vfs-wrap.c */
int vfswrap_dummy_connect(connection_struct *conn, char *service, char *user);

View File

@ -1670,5 +1670,6 @@ typedef struct user_struct
#define MAP_TO_GUEST_ON_BAD_PASSWORD 2
#include "nsswitch/winbindd_nss.h"
#include "smb_acls.h"
#endif /* _SMB_H */

View File

@ -29,6 +29,7 @@
/* This is an identity mapping (just remove the SMB_). */
#define SMB_ACL_TAG_T acl_tag_t
#define SMB_ACL_TYPE_T acl_type_t
#define SMB_ACL_PERMSET_T acl_permset_t
#define SMB_ACL_READ ACL_READ
#define SMB_ACL_WRITE ACL_WRITE
@ -60,6 +61,7 @@
/* No ACLS - fake it. */
#define SMB_ACL_TAG_T int
#define SMB_ACL_TYPE_T int
#define SMB_ACL_PERMSET_T mode_t
#define SMB_ACL_READ S_IRUSR
#define SMB_ACL_WRITE S_IWUSR
@ -73,11 +75,11 @@
#define SMB_ACL_OTHER_OBJ 4
#define SMB_ACL_MASK 5
typdef struct SMB_ACL_T {
typedef struct SMB_ACL_T {
int dummy;
} *SMB_ACL_T;
typdef struct SMB_ACL_ENTRY_T {
typedef struct SMB_ACL_ENTRY_T {
int dummy;
} *SMB_ACL_ENTRY_T;

View File

@ -84,27 +84,39 @@ int sys_acl_free( void *obj_p)
#elif defined(HAVE_IRIX_ACLS)
#else /* No ACLs. */
int sys_acl_get_entry( SMB_ACL_T acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
{
return -1;
}
int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
{
return -1;
}
int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
{
return -1;
}
void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
{
return NULL;
}
SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
{
return (SMB_ACL_T)NULL;
}
SMB_ACL_T sys_acl_get_fd(int fd)
{
return (SMB_ACL_T)NULL;
}
int sys_acl_free( void *obj_p)
{
return -1;
}
#endif /* No ACLs. */

View File

@ -569,6 +569,11 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd)
/* Open the smbpassword file - for update. */
fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth);
if (fp == NULL && errno == ENOENT) {
/* Try again - create. */
fp = startsmbfilepwent(pfile, PWF_CREATE, &pw_file_lock_depth);
}
if (fp == NULL) {
DEBUG(0, ("add_smbfilepwd_entry: unable to open file.\n"));
return False;

View File

@ -120,7 +120,7 @@ END {
gotstart = 1;
}
if( $0 ~ /^SAM_ACCT_INFO_NODE/ ) {
if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T/ ) {
gotstart = 1;
}

View File

@ -1,4 +1,3 @@
#ifdef HAVE_POSIX_ACLS
#define OLD_NTDOMAIN 1
/*
Unix SMB/Netbios implementation.
@ -57,17 +56,16 @@ static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon
/*
* Here we differentiate between the owner and any other user.
*/
if (sid_equal(powner_sid, &ace->sid)
if (sid_equal(powner_sid, &ace->sid)) {
nt_mask = UNIX_ACCESS_NONE;
} else {
/* Not owner, this is an access denied ACE. */
nt_mask = UNIX_ACCESS_RWX;
*pacl_type = SEC_ACE_TYPE_ACCESS_DENIED;
/* Not owner, no access. */
nt_mask = 0;
}
} else {
nt_mask |= (perm & SMB_ACL_READ) ? UNIX_ACCESS_R : 0;
nt_mask |= (perm & SMB_ACL_WRITE) ? UNIX_ACCESS_W : 0;
nt_mask |= (perm & SMB_ACL_EXECUTE) ? UNIX_ACCESS_X : 0;
nt_mask |= (ace->perms & SMB_ACL_READ) ? UNIX_ACCESS_R : 0;
nt_mask |= (ace->perms & SMB_ACL_WRITE) ? UNIX_ACCESS_W : 0;
nt_mask |= (ace->perms & SMB_ACL_EXECUTE) ? UNIX_ACCESS_X : 0;
}
init_sec_access(&sa,nt_mask);
return sa;
@ -130,8 +128,6 @@ static BOOL unpack_nt_permissions(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *p
DOM_SID grp_sid;
DOM_SID file_owner_sid;
DOM_SID file_grp_sid;
uint32 owner_rid;
uint32 grp_rid;
SEC_ACL *dacl = psd->dacl;
BOOL all_aces_are_inherit_only = (is_directory ? True : False);
int i;
@ -360,9 +356,6 @@ static canon_ace *unix_canonicalise_acl(files_struct *fsp, SMB_STRUCT_STAT *psbu
canon_ace *owner_ace = NULL;
canon_ace *group_ace = NULL;
canon_ace *other_ace = NULL;
SMB_ACL_TAG_T type;
SMB_ACL_PERMSET_T perms;
DOM_SID sid;
/*
* Create 3 linked list entries.
@ -371,7 +364,7 @@ static canon_ace *unix_canonicalise_acl(files_struct *fsp, SMB_STRUCT_STAT *psbu
if ((owner_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL)
goto fail;
if ((gtoup_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL)
if ((group_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL)
goto fail;
if ((other_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL)
@ -391,9 +384,9 @@ static canon_ace *unix_canonicalise_acl(files_struct *fsp, SMB_STRUCT_STAT *psbu
other_ace->sid = global_sid_World;
if (!fsp->is_directory) {
owner_ace->perms = unix_perms_to_acl_perms(sbuf.st_mode, S_IRUSR, S_IWUSR, S_IXUSR);
group_ace->perms = unix_perms_to_acl_perms(sbuf.st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
other_ace->perms = unix_perms_to_acl_perms(sbuf.st_mode, S_IROTH, S_IWOTH, S_IXOTH);
owner_ace->perms = unix_perms_to_acl_perms(psbuf->st_mode, S_IRUSR, S_IWUSR, S_IXUSR);
group_ace->perms = unix_perms_to_acl_perms(psbuf->st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
other_ace->perms = unix_perms_to_acl_perms(psbuf->st_mode, S_IROTH, S_IWOTH, S_IXOTH);
} else {
mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name);
@ -450,11 +443,11 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf)
/* Decide which SID to use based on the ACL type. */
switch(tagtype) {
SMB_ACL_USER_OBJ:
case SMB_ACL_USER_OBJ:
/* Get the SID from the owner. */
uid_to_sid( &sid, psbuf->st_uid );
break;
SMB_ACL_USER:
case SMB_ACL_USER:
{
uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry);
if (puid == NULL) {
@ -464,11 +457,11 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf)
uid_to_sid( &sid, *puid);
break;
}
SMB_ACL_GROUP_OBJ:
case SMB_ACL_GROUP_OBJ:
/* Get the SID from the owning group. */
gid_to_sid( &sid, psbuf->st_gid );
break;
SMB_ACL_GROUP:
case SMB_ACL_GROUP:
{
gid_t *pgid = (gid_t *)sys_acl_get_qualifier(entry);
if (pgid == NULL) {
@ -478,10 +471,10 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf)
gid_to_sid( &sid, *pgid);
break;
}
SMB_ACL_MASK:
case SMB_ACL_MASK:
acl_mask = permset;
continue; /* Don't count the mask as an entry. */
SMB_ACL_OTHER_OBJ:
case SMB_ACL_OTHER_OBJ:
/* Use the Everyone SID */
sid = global_sid_World;
break;
@ -515,18 +508,18 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf)
*/
for ( ace = list_head; ace; ace = next_ace) {
next_ace = ace_next;
next_ace = ace->next;
ace->perms &= acl_mask;
if (ace->perms == 0) {
switch (ace->type) {
SMB_ACL_USER_OBJ:
SMB_ACL_GROUP_OBJ:
SMB_ACL_OTHER_OBJ:
case SMB_ACL_USER_OBJ:
case SMB_ACL_GROUP_OBJ:
case SMB_ACL_OTHER_OBJ:
DLIST_REMOVE(list_head, ace);
break;
SMB_ACL_USER:
SMB_ACL_GROUP:
case SMB_ACL_USER:
case SMB_ACL_GROUP:
DLIST_PROMOTE(list_head, ace);
break;
}
@ -534,6 +527,11 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf)
}
return list_head;
fail:
free_canon_ace_list(list_head);
return NULL;
}
/****************************************************************************
@ -545,19 +543,12 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf)
size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
{
extern DOM_SID global_sid_World;
SMB_STRUCT_STAT sbuf;
SEC_ACE *nt_ace_list;
DOM_SID owner_sid;
DOM_SID group_sid;
size_t sd_size = 0;
SEC_ACL *psa = NULL;
SEC_ACCESS owner_access;
int owner_acl_type;
SEC_ACCESS group_access;
int grp_acl_type;
SEC_ACCESS other_access;
int other_acl_type;
size_t num_acls = 0;
size_t num_dir_acls = 0;
size_t num_aces = 0;
@ -571,7 +562,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
if(fsp->is_directory || fsp->fd == -1) {
/* Get the stat struct for the owner info. */
if(vfs_stat(fsp,fsp->fsp_name, &sbuf) != 0) {
if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
return 0;
}
/*
@ -590,7 +581,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
} else {
/* Get the stat struct for the owner info. */
if(fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
return 0;
}
/*
@ -625,7 +616,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
/* Allocate the ace list. */
if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
goto done:
goto done;
}
memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
@ -637,6 +628,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
{
canon_ace *ace;
int nt_acl_type;
int i;
ace = file_ace;
@ -655,7 +647,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
}
if (num_acls) {
if((psa = make_sec_acl( ACL_REVISION, num_aces, ace_list)) == NULL) {
if((psa = make_sec_acl( ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
goto done;
}
@ -672,8 +664,8 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
if (posix_acl)
sys_acl_free(posix_acl);
if (directory_acl)
sys_acl_free(directory_acl);
if (dir_acl)
sys_acl_free(dir_acl);
if (file_ace)
free_canon_ace_list(file_ace);
if (dir_ace)
@ -705,19 +697,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
* Get the current state of the file.
*/
if(fsp->is_directory) {
if(dos_stat(fsp->fsp_name, &sbuf) != 0)
if(fsp->is_directory || fsp->fd == -1) {
if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0)
return False;
} else {
int ret;
if(fsp->fd == -1)
ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
else
ret = conn->vfs_ops.fstat(fsp->fd,&sbuf);
if(ret != 0)
if(conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0)
return False;
}
@ -740,7 +724,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
DEBUG(3,("call_nt_transact_set_security_desc: chown %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
if(dos_chown( fsp->fsp_name, user, grp) == -1) {
if(vfs_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
DEBUG(3,("call_nt_transact_set_security_desc: chown %s, %u, %u failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
return False;
@ -752,7 +736,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
*/
if(fsp->is_directory) {
if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
if(vfs_stat(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
return False;
}
} else {
@ -760,9 +744,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
int ret;
if(fsp->fd == -1)
ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
ret = vfs_stat(fsp->conn, fsp->fsp_name, &sbuf);
else
ret = conn->vfs_ops.fstat(fsp->fd,&sbuf);
ret = conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf);
if(ret != 0)
return False;
@ -808,7 +792,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
fsp->fsp_name, (unsigned int)perms ));
if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) {
if(conn->vfs_ops.chmod(conn,dos_to_unix(fsp->fsp_name, False), perms) == -1) {
DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)perms, strerror(errno) ));
return False;
@ -819,6 +803,8 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
return True;
}
#undef OLD_NTDOMAIN
#else /* HAVE_POSIX_ACLS */
void dummy_posix_acls(void) {;} /* So some compilers don't complain. */
#endif /* HAVE_POSIX_ACLS */