mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
Fixes for POSIX ACLS. ACL merge code.
Jeremy. (This used to be commit 180e4a9cd05bcadb2f7c4c23d653724e867196f0)
This commit is contained in:
parent
e870dd2988
commit
7786e07735
@ -575,6 +575,8 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
|||||||
|
|
||||||
DOM_SID dom_sid;
|
DOM_SID dom_sid;
|
||||||
uint32 rid;
|
uint32 rid;
|
||||||
|
fstring str;
|
||||||
|
struct passwd *pass;
|
||||||
|
|
||||||
*name_type = SID_NAME_UNKNOWN;
|
*name_type = SID_NAME_UNKNOWN;
|
||||||
|
|
||||||
@ -593,9 +595,12 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
|||||||
/*
|
/*
|
||||||
* Ensure this uid really does exist.
|
* Ensure this uid really does exist.
|
||||||
*/
|
*/
|
||||||
if(!sys_getpwuid(*puid))
|
if(!(pass = sys_getpwuid(*puid)))
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
|
DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
|
||||||
|
(unsigned int)*puid, pass->pw_name ));
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,6 +625,8 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
|||||||
extern DOM_SID global_sam_sid;
|
extern DOM_SID global_sam_sid;
|
||||||
DOM_SID dom_sid;
|
DOM_SID dom_sid;
|
||||||
uint32 rid;
|
uint32 rid;
|
||||||
|
fstring str;
|
||||||
|
struct group *grp;
|
||||||
|
|
||||||
*name_type = SID_NAME_UNKNOWN;
|
*name_type = SID_NAME_UNKNOWN;
|
||||||
|
|
||||||
@ -640,9 +647,12 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
|||||||
* Ensure this gid really does exist.
|
* Ensure this gid really does exist.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(!getgrgid(*pgid))
|
if(!(grp = getgrgid(*pgid)))
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
|
DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u) (%s).\n", sid_to_string( str, psid),
|
||||||
|
(unsigned int)*pgid, grp->gr_name ));
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,24 +41,6 @@ typedef struct canon_ace {
|
|||||||
|
|
||||||
static void free_canon_ace_list( canon_ace *list_head );
|
static void free_canon_ace_list( canon_ace *list_head );
|
||||||
|
|
||||||
#if 0
|
|
||||||
/****************************************************************************
|
|
||||||
Function to duplicate a canon_ace struct.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static canon_ace *dup_canon_ace( canon_ace *c_ace)
|
|
||||||
{
|
|
||||||
canon_ace *new_ace = (canon_ace *)malloc(sizeof(canon_ace));
|
|
||||||
|
|
||||||
if (new_ace == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
*new_ace = *c_ace;
|
|
||||||
|
|
||||||
return new_ace;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Function to create owner and group SIDs from a SMB_STRUCT_STAT.
|
Function to create owner and group SIDs from a SMB_STRUCT_STAT.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -69,6 +51,47 @@ static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SI
|
|||||||
gid_to_sid( pgroup_sid, psbuf->st_gid );
|
gid_to_sid( pgroup_sid, psbuf->st_gid );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Print out a canon ace.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void print_canon_ace(canon_ace *ace, int num)
|
||||||
|
{
|
||||||
|
fstring str;
|
||||||
|
|
||||||
|
dbgtext( "canon_ace index %d.", num );
|
||||||
|
dbgtext( "SID = %s ", sid_to_string( str, &ace->sid));
|
||||||
|
if (ace->owner_type == UID_ACE) {
|
||||||
|
struct passwd *pass = sys_getpwuid(ace->unix_ug.uid);
|
||||||
|
dbgtext( "uid %u (%s) ", (unsigned int)ace->unix_ug.uid, pass ? pass->pw_name : "UNKNOWN");
|
||||||
|
} else if (ace->owner_type == GID_ACE) {
|
||||||
|
struct group *grp = getgrgid(ace->unix_ug.gid);
|
||||||
|
dbgtext( "gid %u (%s) ", (unsigned int)ace->unix_ug.gid, grp ? grp->gr_name : "UNKNOWN");
|
||||||
|
} else
|
||||||
|
dbgtext( "other ");
|
||||||
|
switch (ace->type) {
|
||||||
|
case SMB_ACL_USER:
|
||||||
|
dbgtext( "SMB_ACL_USER ");
|
||||||
|
break;
|
||||||
|
case SMB_ACL_USER_OBJ:
|
||||||
|
dbgtext( "SMB_ACL_USER_OBJ ");
|
||||||
|
break;
|
||||||
|
case SMB_ACL_GROUP:
|
||||||
|
dbgtext( "SMB_ACL_GROUP ");
|
||||||
|
break;
|
||||||
|
case SMB_ACL_GROUP_OBJ:
|
||||||
|
dbgtext( "SMB_ACL_GROUP_OBJ ");
|
||||||
|
break;
|
||||||
|
case SMB_ACL_OTHER:
|
||||||
|
dbgtext( "SMB_ACL_OTHER ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dbgtext( "perms ");
|
||||||
|
dbgtext( "%c", ace->perms & S_IRUSR ? 'r' : '-');
|
||||||
|
dbgtext( "%c", ace->perms & S_IWUSR ? 'w' : '-');
|
||||||
|
dbgtext( "%c\n", ace->perms & S_IXUSR ? 'x' : '-');
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Map canon_ace perms to permission bits NT.
|
Map canon_ace perms to permission bits NT.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -80,9 +103,9 @@ static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon
|
|||||||
|
|
||||||
*pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
|
*pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
|
||||||
|
|
||||||
if((ace->perms & (S_IRWXU|S_IWUSR|S_IXUSR)) == (S_IRWXU|S_IWUSR|S_IXUSR)) {
|
if((ace->perms & (S_IRUSR|S_IWUSR|S_IXUSR)) == (S_IRUSR|S_IWUSR|S_IXUSR)) {
|
||||||
nt_mask = UNIX_ACCESS_RWX;
|
nt_mask = UNIX_ACCESS_RWX;
|
||||||
} else if((ace->perms & (S_IRWXU|S_IWUSR|S_IXUSR)) == 0) {
|
} else if((ace->perms & (S_IRUSR|S_IWUSR|S_IXUSR)) == 0) {
|
||||||
/*
|
/*
|
||||||
* Here we differentiate between the owner and any other user.
|
* Here we differentiate between the owner and any other user.
|
||||||
*/
|
*/
|
||||||
@ -93,7 +116,7 @@ static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon
|
|||||||
nt_mask = 0;
|
nt_mask = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nt_mask |= ((ace->perms & S_IRWXU) ? UNIX_ACCESS_R : 0 );
|
nt_mask |= ((ace->perms & S_IRUSR) ? UNIX_ACCESS_R : 0 );
|
||||||
nt_mask |= ((ace->perms & S_IWUSR) ? UNIX_ACCESS_W : 0 );
|
nt_mask |= ((ace->perms & S_IWUSR) ? UNIX_ACCESS_W : 0 );
|
||||||
nt_mask |= ((ace->perms & S_IXUSR) ? UNIX_ACCESS_X : 0 );
|
nt_mask |= ((ace->perms & S_IXUSR) ? UNIX_ACCESS_X : 0 );
|
||||||
}
|
}
|
||||||
@ -202,6 +225,34 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Merge aces with a common user.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static BOOL merge_aces( canon_ace *list_head, canon_ace *p_ace)
|
||||||
|
{
|
||||||
|
canon_ace *curr_ace;
|
||||||
|
|
||||||
|
for (curr_ace = list_head; curr_ace; curr_ace = curr_ace->next) {
|
||||||
|
if (curr_ace == p_ace)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (curr_ace->type == p_ace->type && sid_equal(&curr_ace->sid, &p_ace->sid)) {
|
||||||
|
if( DEBUGLVL( 10 )) {
|
||||||
|
dbgtext("Merging ACE's\n");
|
||||||
|
print_canon_ace( p_ace, 0);
|
||||||
|
print_canon_ace( curr_ace, 0);
|
||||||
|
}
|
||||||
|
p_ace->perms |= curr_ace->perms;
|
||||||
|
DLIST_REMOVE(list_head, curr_ace);
|
||||||
|
free(curr_ace);
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Unpack a SEC_DESC into two canonical ace lists. We don't depend on this
|
Unpack a SEC_DESC into two canonical ace lists. We don't depend on this
|
||||||
succeeding.
|
succeeding.
|
||||||
@ -218,6 +269,7 @@ static BOOL unpack_canon_ace(files_struct *fsp,
|
|||||||
BOOL all_aces_are_inherit_only = (fsp->is_directory ? True : False);
|
BOOL all_aces_are_inherit_only = (fsp->is_directory ? True : False);
|
||||||
canon_ace *file_ace = NULL;
|
canon_ace *file_ace = NULL;
|
||||||
canon_ace *dir_ace = NULL;
|
canon_ace *dir_ace = NULL;
|
||||||
|
canon_ace *current_ace = NULL;
|
||||||
enum SID_NAME_USE sid_type;
|
enum SID_NAME_USE sid_type;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -242,7 +294,6 @@ static BOOL unpack_canon_ace(files_struct *fsp,
|
|||||||
|
|
||||||
for(i = 0; i < dacl->num_aces; i++) {
|
for(i = 0; i < dacl->num_aces; i++) {
|
||||||
SEC_ACE *psa = &dacl->ace[i];
|
SEC_ACE *psa = &dacl->ace[i];
|
||||||
canon_ace *current_ace = NULL;
|
|
||||||
|
|
||||||
if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) && (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
|
if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) && (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
|
||||||
DEBUG(3,("unpack_canon_ace: unable to set anything but an ALLOW or DENY ACE.\n"));
|
DEBUG(3,("unpack_canon_ace: unable to set anything but an ALLOW or DENY ACE.\n"));
|
||||||
@ -308,7 +359,7 @@ static BOOL unpack_canon_ace(files_struct *fsp,
|
|||||||
if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
|
if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
|
||||||
current_ace->perms |= map_nt_perms( psa->info, S_IRUSR);
|
current_ace->perms |= map_nt_perms( psa->info, S_IRUSR);
|
||||||
else
|
else
|
||||||
current_ace->perms &= ~(map_nt_perms( psa->info, S_IRUSR));
|
current_ace->perms = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now note what kind of a POSIX ACL this should map to.
|
* Now note what kind of a POSIX ACL this should map to.
|
||||||
@ -357,10 +408,29 @@ static BOOL unpack_canon_ace(files_struct *fsp,
|
|||||||
* there was no DACL sent. JRA.
|
* there was no DACL sent. JRA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUG(10,("unpack_posix_permissions: Win2k inherit acl traverse. Ignoring DACL.\n"));
|
DEBUG(10,("unpack_canon_ace: Win2k inherit acl traverse. Ignoring DACL.\n"));
|
||||||
free_sec_acl(&psd->dacl);
|
free_sec_acl(&psd->dacl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now go through the canon_ace lists and merge entries
|
||||||
|
* belonging to identical users.
|
||||||
|
*/
|
||||||
|
|
||||||
|
again_file:
|
||||||
|
|
||||||
|
for (current_ace = file_ace; current_ace; current_ace = current_ace->next ) {
|
||||||
|
if (merge_aces( file_ace, current_ace))
|
||||||
|
goto again_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
again_dir:
|
||||||
|
|
||||||
|
for (current_ace = dir_ace; current_ace; current_ace = current_ace->next ) {
|
||||||
|
if (merge_aces( dir_ace, current_ace))
|
||||||
|
goto again_dir;
|
||||||
|
}
|
||||||
|
|
||||||
*ppfile_ace = file_ace;
|
*ppfile_ace = file_ace;
|
||||||
*ppdir_ace = dir_ace;
|
*ppdir_ace = dir_ace;
|
||||||
return True;
|
return True;
|
||||||
@ -371,7 +441,7 @@ static BOOL unpack_canon_ace(files_struct *fsp,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static BOOL unpack_posix_permissions(files_struct *fsp, SMB_STRUCT_STAT *psbuf, mode_t *pmode,
|
static BOOL unpack_posix_permissions(files_struct *fsp, SMB_STRUCT_STAT *psbuf, mode_t *pmode,
|
||||||
uint32 security_info_sent, SEC_DESC *psd)
|
uint32 security_info_sent, SEC_DESC *psd, BOOL posix_acls)
|
||||||
{
|
{
|
||||||
extern DOM_SID global_sid_World;
|
extern DOM_SID global_sid_World;
|
||||||
connection_struct *conn = fsp->conn;
|
connection_struct *conn = fsp->conn;
|
||||||
@ -478,6 +548,7 @@ static BOOL unpack_posix_permissions(files_struct *fsp, SMB_STRUCT_STAT *psbuf,
|
|||||||
else
|
else
|
||||||
*pmode &= ~(map_nt_perms( psa->info, S_IRUSR));
|
*pmode &= ~(map_nt_perms( psa->info, S_IRUSR));
|
||||||
|
|
||||||
|
|
||||||
} else if( sid_equal(&ace_sid, &file_grp_sid)) {
|
} else if( sid_equal(&ace_sid, &file_grp_sid)) {
|
||||||
/*
|
/*
|
||||||
* Map the desired permissions into group perms.
|
* Map the desired permissions into group perms.
|
||||||
@ -499,6 +570,11 @@ static BOOL unpack_posix_permissions(files_struct *fsp, SMB_STRUCT_STAT *psbuf,
|
|||||||
*pmode &= ~(map_nt_perms( psa->info, S_IROTH));
|
*pmode &= ~(map_nt_perms( psa->info, S_IROTH));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
|
* Only bother printing the level zero error if we didn't get any
|
||||||
|
* POSIX ACLS.
|
||||||
|
*/
|
||||||
|
if (!posix_acls)
|
||||||
DEBUG(0,("unpack_posix_permissions: unknown SID used in ACL.\n"));
|
DEBUG(0,("unpack_posix_permissions: unknown SID used in ACL.\n"));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
@ -926,6 +1002,9 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
|
|||||||
i, strerror(errno) ));
|
i, strerror(errno) ));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( DEBUGLVL( 10 ))
|
||||||
|
print_canon_ace( p_ace, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1019,6 +1098,8 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
|
|||||||
|
|
||||||
*ppdesc = NULL;
|
*ppdesc = NULL;
|
||||||
|
|
||||||
|
DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name ));
|
||||||
|
|
||||||
if(fsp->is_directory || fsp->fd == -1) {
|
if(fsp->is_directory || fsp->fd == -1) {
|
||||||
|
|
||||||
/* Get the stat struct for the owner info. */
|
/* Get the stat struct for the owner info. */
|
||||||
@ -1160,6 +1241,8 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
|
|||||||
BOOL posix_perms;
|
BOOL posix_perms;
|
||||||
BOOL acl_perms;
|
BOOL acl_perms;
|
||||||
|
|
||||||
|
DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the current state of the file.
|
* Get the current state of the file.
|
||||||
*/
|
*/
|
||||||
@ -1219,9 +1302,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
|
|||||||
|
|
||||||
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
|
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
|
||||||
|
|
||||||
posix_perms = unpack_posix_permissions( fsp, &sbuf, &perms, security_info_sent, psd);
|
|
||||||
acl_perms = unpack_canon_ace( fsp, &file_owner_sid, &file_grp_sid,
|
acl_perms = unpack_canon_ace( fsp, &file_owner_sid, &file_grp_sid,
|
||||||
&file_ace_list, &dir_ace_list, security_info_sent, psd);
|
&file_ace_list, &dir_ace_list, security_info_sent, psd);
|
||||||
|
posix_perms = unpack_posix_permissions( fsp, &sbuf, &perms, security_info_sent, psd, acl_perms);
|
||||||
|
|
||||||
if (!posix_perms && !acl_perms) {
|
if (!posix_perms && !acl_perms) {
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user