1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +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 used to be commit 4339e20202)
This commit is contained in:
Jeremy Allison 2000-12-06 23:24:31 +00:00
parent e899f04a68
commit 70922b9bbe
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 */