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

Fixes for POSIX ACLS. ACL merge code.

Jeremy.
(This used to be commit 180e4a9cd0)
This commit is contained in:
Jeremy Allison 2001-01-15 22:46:22 +00:00
parent e870dd2988
commit 7786e07735
2 changed files with 122 additions and 29 deletions

View File

@ -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;
uint32 rid;
fstring str;
struct passwd *pass;
*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.
*/
if(!sys_getpwuid(*puid))
if(!(pass = sys_getpwuid(*puid)))
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;
}
@ -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;
DOM_SID dom_sid;
uint32 rid;
fstring str;
struct group *grp;
*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.
*/
if(!getgrgid(*pgid))
if(!(grp = getgrgid(*pgid)))
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;
}

View File

@ -41,24 +41,6 @@ typedef struct canon_ace {
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.
****************************************************************************/
@ -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 );
}
/****************************************************************************
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.
****************************************************************************/
@ -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;
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;
} 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.
*/
@ -93,7 +116,7 @@ static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon
nt_mask = 0;
}
} 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_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;
}
/****************************************************************************
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
succeeding.
@ -218,6 +269,7 @@ static BOOL unpack_canon_ace(files_struct *fsp,
BOOL all_aces_are_inherit_only = (fsp->is_directory ? True : False);
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
canon_ace *current_ace = NULL;
enum SID_NAME_USE sid_type;
int i;
@ -242,7 +294,6 @@ static BOOL unpack_canon_ace(files_struct *fsp,
for(i = 0; i < dacl->num_aces; 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)) {
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)
current_ace->perms |= map_nt_perms( psa->info, S_IRUSR);
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.
@ -357,10 +408,29 @@ static BOOL unpack_canon_ace(files_struct *fsp,
* 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);
}
/*
* 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;
*ppdir_ace = dir_ace;
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,
uint32 security_info_sent, SEC_DESC *psd)
uint32 security_info_sent, SEC_DESC *psd, BOOL posix_acls)
{
extern DOM_SID global_sid_World;
connection_struct *conn = fsp->conn;
@ -478,6 +548,7 @@ static BOOL unpack_posix_permissions(files_struct *fsp, SMB_STRUCT_STAT *psbuf,
else
*pmode &= ~(map_nt_perms( psa->info, S_IRUSR));
} else if( sid_equal(&ace_sid, &file_grp_sid)) {
/*
* 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));
} 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"));
return False;
}
@ -926,6 +1002,9 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
i, strerror(errno) ));
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;
DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name ));
if(fsp->is_directory || fsp->fd == -1) {
/* 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 acl_perms;
DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
/*
* 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);
posix_perms = unpack_posix_permissions( fsp, &sbuf, &perms, security_info_sent, psd);
acl_perms = unpack_canon_ace( fsp, &file_owner_sid, &file_grp_sid,
&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) {
/*