static struct security_descriptor *file_get_sd( struct object *obj ) { struct file *file = (struct file *)obj; struct stat st; int unix_fd; struct security_descriptor *sd; assert( obj->ops == &file_ops ); unix_fd = get_file_unix_fd( file ); if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return obj->sd; /* mode and uid the same? if so, no need to re-generate security descriptor */ if (obj->sd && (st.st_mode & (S_IRWXU|S_IRWXO)) == (file->mode & (S_IRWXU|S_IRWXO)) && (st.st_uid == file->uid)) return obj->sd; sd = mode_to_sd( st.st_mode, security_unix_uid_to_sid( st.st_uid ), token_get_primary_group( current->process->token )); if (!sd) return obj->sd; file->mode = st.st_mode; file->uid = st.st_uid; free( obj->sd ); obj->sd = sd; return sd; }
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid ) { int unix_fd = get_unix_fd( fd ); struct stat st; struct security_descriptor *sd; const SID *user, *group; if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return obj->sd; /* mode and uid the same? if so, no need to re-generate security descriptor */ if (obj->sd && (st.st_mode & (S_IRWXU|S_IRWXO)) == (*mode & (S_IRWXU|S_IRWXO)) && (st.st_uid == *uid)) return obj->sd; user = security_unix_uid_to_sid( st.st_uid ); group = token_get_primary_group( current->process->token ); sd = get_xattr_sd( unix_fd ); if (!sd) sd = get_xattr_acls( unix_fd, user, group ); if (sd) convert_generic_sd( sd ); if (!sd) sd = mode_to_sd( st.st_mode, user, group ); if (!sd) return obj->sd; *mode = st.st_mode; *uid = st.st_uid; free( obj->sd ); obj->sd = sd; return sd; }