Reorganized ACL inheritance to allow inheritance in directories with a
parent
3db8bb1848
commit
86084908e2
|
@ -46,6 +46,8 @@ struct MAPPING {
|
|||
struct CACHED_PERMISSIONS {
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
le32 inh_fileid;
|
||||
le32 inh_dirid;
|
||||
unsigned int mode:9;
|
||||
unsigned int valid:1;
|
||||
} ;
|
||||
|
@ -157,6 +159,8 @@ int ntfs_set_owner(struct SECURITY_CONTEXT *scx,
|
|||
int ntfs_set_owner_mode(struct SECURITY_CONTEXT *scx,
|
||||
ntfs_inode *ni,
|
||||
uid_t uid, gid_t gid, mode_t mode);
|
||||
le32 ntfs_inherited_id(struct SECURITY_CONTEXT *scx,
|
||||
const char *dir_path, ntfs_inode *dir_ni, BOOL fordir);
|
||||
int ntfs_open_secure(ntfs_volume *vol);
|
||||
void ntfs_close_secure(struct SECURITY_CONTEXT *scx);
|
||||
|
||||
|
|
|
@ -1761,6 +1761,8 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx,
|
|||
cacheentry->uid = uid;
|
||||
cacheentry->gid = gid;
|
||||
cacheentry->mode = mode & 0777;
|
||||
cacheentry->inh_fileid = cpu_to_le32(0);
|
||||
cacheentry->inh_dirid = cpu_to_le32(0);
|
||||
cacheentry->valid = 1;
|
||||
pcache->head.p_writes++;
|
||||
} else {
|
||||
|
@ -1776,6 +1778,8 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx,
|
|||
cacheentry->uid = uid;
|
||||
cacheentry->gid = gid;
|
||||
cacheentry->mode = mode & 0777;
|
||||
cacheentry->inh_fileid = cpu_to_le32(0);
|
||||
cacheentry->inh_dirid = cpu_to_le32(0);
|
||||
cacheentry->valid = 1;
|
||||
pcache->head.p_writes++;
|
||||
}
|
||||
|
@ -1828,7 +1832,7 @@ static struct CACHED_PERMISSIONS *fetch_cache(struct SECURITY_CONTEXT *scx,
|
|||
* Retrieve a security attribute from $Secure
|
||||
*/
|
||||
|
||||
static char *retrievesecurityattr(struct SECURITY_CONTEXT *scx, SII_INDEX_KEY id)
|
||||
static char *retrievesecurityattr(ntfs_volume *vol, SII_INDEX_KEY id)
|
||||
{
|
||||
struct SII *psii;
|
||||
union {
|
||||
|
@ -1847,8 +1851,8 @@ static char *retrievesecurityattr(struct SECURITY_CONTEXT *scx, SII_INDEX_KEY id
|
|||
char *securattr;
|
||||
|
||||
securattr = (char*)NULL;
|
||||
ni = scx->vol->secure_ni;
|
||||
xsii = scx->vol->secure_xsii;
|
||||
ni = vol->secure_ni;
|
||||
xsii = vol->secure_xsii;
|
||||
ntfs_index_ctx_reinit(xsii);
|
||||
if (xsii) {
|
||||
found =
|
||||
|
@ -2229,7 +2233,7 @@ static char *build_secur_descr(mode_t mode,
|
|||
if (newattr) {
|
||||
/* build the main header part */
|
||||
pnhead = (SECURITY_DESCRIPTOR_RELATIVE*) newattr;
|
||||
pnhead->revision = 1;
|
||||
pnhead->revision = SECURITY_DESCRIPTOR_REVISION;
|
||||
pnhead->alignment = 0;
|
||||
pnhead->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
|
||||
/*
|
||||
|
@ -2281,7 +2285,7 @@ static char *build_secur_descr(mode_t mode,
|
|||
* The returned descriptor is dynamically allocated and has to be freed
|
||||
*/
|
||||
|
||||
static char *getsecurityattr(struct SECURITY_CONTEXT *scx,
|
||||
static char *getsecurityattr(ntfs_volume *vol,
|
||||
const char *path, ntfs_inode *ni)
|
||||
{
|
||||
SII_INDEX_KEY securid;
|
||||
|
@ -2297,7 +2301,7 @@ static char *getsecurityattr(struct SECURITY_CONTEXT *scx,
|
|||
if (test_nino_flag(ni, v3_Extensions) && ni->security_id) {
|
||||
/* get v3.x descriptor in $Secure */
|
||||
securid.security_id = ni->security_id;
|
||||
securattr = retrievesecurityattr(scx,securid);
|
||||
securattr = retrievesecurityattr(vol,securid);
|
||||
if (!securattr)
|
||||
ntfs_log_error("Bad security descriptor for 0x%lx\n",
|
||||
(long)le32_to_cpu(ni->security_id));
|
||||
|
@ -2688,7 +2692,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
|
|||
gid = cached->gid;
|
||||
} else {
|
||||
perm = 0; /* default to no permission */
|
||||
securattr = getsecurityattr(scx, path, ni);
|
||||
securattr = getsecurityattr(scx->vol, path, ni);
|
||||
if (securattr) {
|
||||
perm = build_permissions(securattr, ni);
|
||||
/*
|
||||
|
@ -2766,7 +2770,7 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
|
|||
stbuf->st_mode = (stbuf->st_mode & ~0777) + perm;
|
||||
} else {
|
||||
perm = -1; /* default to error */
|
||||
securattr = getsecurityattr(scx, path, ni);
|
||||
securattr = getsecurityattr(scx->vol, path, ni);
|
||||
if (securattr) {
|
||||
perm = build_permissions(securattr, ni);
|
||||
/*
|
||||
|
@ -2906,7 +2910,7 @@ int ntfs_set_mode(struct SECURITY_CONTEXT *scx,
|
|||
fileuid = cached->uid;
|
||||
filegid = cached->gid;
|
||||
} else {
|
||||
oldattr = getsecurityattr(scx,path, ni);
|
||||
oldattr = getsecurityattr(scx->vol,path, ni);
|
||||
if (oldattr) {
|
||||
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)oldattr;
|
||||
usid = (const SID*)&oldattr[le32_to_cpu(phead->owner)];
|
||||
|
@ -2960,11 +2964,11 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||
if (!sd)
|
||||
return -1;
|
||||
|
||||
sd->revision = 1;
|
||||
sd->revision = SECURITY_DESCRIPTOR_REVISION;
|
||||
sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
|
||||
|
||||
sid = (SID*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_ATTR));
|
||||
sid->revision = 1;
|
||||
sid->revision = SID_REVISION;
|
||||
sid->sub_authority_count = 2;
|
||||
sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
|
||||
sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
|
||||
|
@ -2972,7 +2976,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||
sd->owner = cpu_to_le32((u8*)sid - (u8*)sd);
|
||||
|
||||
sid = (SID*)((u8*)sid + sizeof(SID) + 4);
|
||||
sid->revision = 1;
|
||||
sid->revision = SID_REVISION;
|
||||
sid->sub_authority_count = 2;
|
||||
sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
|
||||
sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
|
||||
|
@ -2980,7 +2984,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||
sd->group = cpu_to_le32((u8*)sid - (u8*)sd);
|
||||
|
||||
acl = (ACL*)((u8*)sid + sizeof(SID) + 4);
|
||||
acl->revision = 2;
|
||||
acl->revision = ACL_REVISION;
|
||||
acl->size = cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE));
|
||||
acl->ace_count = cpu_to_le16(1);
|
||||
sd->dacl = cpu_to_le32((u8*)acl - (u8*)sd);
|
||||
|
@ -2990,7 +2994,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||
ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
|
||||
ace->size = cpu_to_le16(sizeof(ACCESS_ALLOWED_ACE));
|
||||
ace->mask = cpu_to_le32(0x1f01ff); /* FIXME */
|
||||
ace->sid.revision = 1;
|
||||
ace->sid.revision = SID_REVISION;
|
||||
ace->sid.sub_authority_count = 1;
|
||||
ace->sid.sub_authority[0] = cpu_to_le32(0);
|
||||
ace->sid.identifier_authority.value[5] = 1;
|
||||
|
@ -3124,7 +3128,7 @@ int ntfs_set_owner(struct SECURITY_CONTEXT *scx,
|
|||
fileuid = 0;
|
||||
filegid = 0;
|
||||
mode = 0;
|
||||
oldattr = getsecurityattr(scx, path, ni);
|
||||
oldattr = getsecurityattr(scx->vol, path, ni);
|
||||
if (oldattr) {
|
||||
mode = perm = build_permissions(oldattr, ni);
|
||||
if (perm >= 0) {
|
||||
|
@ -3167,6 +3171,232 @@ int ntfs_set_owner(struct SECURITY_CONTEXT *scx,
|
|||
return (res ? -1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the inheritable parts of an ACL
|
||||
*
|
||||
* Returns the size of the new ACL
|
||||
* or zero if nothing is inheritable
|
||||
*/
|
||||
|
||||
static int inherit_acl(const ACL *oldacl, ACL *newacl, BOOL fordir)
|
||||
{
|
||||
int src;
|
||||
int dst;
|
||||
int oldcnt;
|
||||
int newcnt;
|
||||
unsigned int selection;
|
||||
int nace;
|
||||
int acesz;
|
||||
const ACCESS_ALLOWED_ACE *poldace;
|
||||
ACCESS_ALLOWED_ACE *pnewace;
|
||||
|
||||
/* ACL header */
|
||||
|
||||
newacl->revision = ACL_REVISION;
|
||||
newacl->alignment1 = 0;
|
||||
newacl->alignment2 = cpu_to_le16(0);
|
||||
src = dst = sizeof(ACL);
|
||||
|
||||
selection = (fordir ? CONTAINER_INHERIT_ACE : OBJECT_INHERIT_ACE);
|
||||
newcnt = 0;
|
||||
oldcnt = le16_to_cpu(oldacl->ace_count);
|
||||
for (nace = 0; nace < oldcnt; nace++) {
|
||||
poldace = (const ACCESS_ALLOWED_ACE*)((char*)oldacl + src);
|
||||
acesz = le16_to_cpu(poldace->size);
|
||||
if (poldace->flags & selection) {
|
||||
pnewace = (ACCESS_ALLOWED_ACE*)
|
||||
((char*)newacl + dst);
|
||||
memcpy(pnewace,poldace,acesz);
|
||||
/* remove inheritance flags if not a directory */
|
||||
if (!fordir)
|
||||
pnewace->flags &= ~(OBJECT_INHERIT_ACE
|
||||
| CONTAINER_INHERIT_ACE);
|
||||
dst += acesz;
|
||||
newcnt++;
|
||||
}
|
||||
src += acesz;
|
||||
}
|
||||
/*
|
||||
* Adjust header if something was inherited
|
||||
*/
|
||||
if (dst > sizeof(ACL)) {
|
||||
newacl->ace_count = cpu_to_le16(newcnt);
|
||||
newacl->size = cpu_to_le16(dst);
|
||||
} else
|
||||
dst = 0;
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a security id for descriptor inherited from
|
||||
* parent directory
|
||||
*/
|
||||
|
||||
static le32 build_inherited_id(struct SECURITY_CONTEXT *scx,
|
||||
const char *parentattr,
|
||||
ntfs_inode *dir_ni, BOOL fordir)
|
||||
{
|
||||
const SECURITY_DESCRIPTOR_RELATIVE *pphead;
|
||||
const ACL *ppacl;
|
||||
const SID *usid;
|
||||
const SID *gsid;
|
||||
int offpacl;
|
||||
int offowner;
|
||||
int offgroup;
|
||||
SECURITY_DESCRIPTOR_RELATIVE *pnhead;
|
||||
ACL *pnacl;
|
||||
int parentattrsz;
|
||||
char *newattr;
|
||||
int newattrsz;
|
||||
int aclsz;
|
||||
int usidsz;
|
||||
int gsidsz;
|
||||
int pos;
|
||||
le32 securid;
|
||||
|
||||
parentattrsz = attr_size(parentattr);
|
||||
if (scx->usermapping) {
|
||||
usid = find_usid(scx, scx->uid);
|
||||
gsid = find_gsid(scx, scx->gid);
|
||||
} else
|
||||
usid = gsid = (const SID*)NULL;
|
||||
/*
|
||||
* new attribute is smaller than parent's
|
||||
* except for differences in SIDs
|
||||
*/
|
||||
newattrsz = parentattrsz;
|
||||
if (usid) newattrsz += sid_size(usid);
|
||||
if (gsid) newattrsz += sid_size(gsid);
|
||||
newattr = (char*)malloc(parentattrsz);
|
||||
if (newattr) {
|
||||
pphead = (const SECURITY_DESCRIPTOR_RELATIVE*)parentattr;
|
||||
pnhead = (SECURITY_DESCRIPTOR_RELATIVE*)newattr;
|
||||
pnhead->revision = SECURITY_DESCRIPTOR_REVISION;
|
||||
pnhead->alignment = 0;
|
||||
pnhead->control = SE_SELF_RELATIVE;
|
||||
pos = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
|
||||
/*
|
||||
* locate and inherit DACL
|
||||
*/
|
||||
pnhead->dacl = cpu_to_le32(0);
|
||||
if (pphead->control & SE_DACL_PRESENT) {
|
||||
offpacl = le32_to_cpu(pphead->dacl);
|
||||
ppacl = (const ACL*)&parentattr[offpacl];
|
||||
pnacl = (ACL*)&newattr[pos];
|
||||
aclsz = inherit_acl(ppacl, pnacl, fordir);
|
||||
if (aclsz) {
|
||||
pnhead->dacl = cpu_to_le32(pos);
|
||||
pos += aclsz;
|
||||
pnhead->control |= SE_DACL_PRESENT;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* locate and inherit SACL
|
||||
*/
|
||||
pnhead->sacl = cpu_to_le32(0);
|
||||
if (pphead->control & SE_SACL_PRESENT) {
|
||||
offpacl = le32_to_cpu(pphead->sacl);
|
||||
ppacl = (const ACL*)&parentattr[offpacl];
|
||||
pnacl = (ACL*)&newattr[pos];
|
||||
aclsz = inherit_acl(ppacl, pnacl, fordir);
|
||||
if (aclsz) {
|
||||
pnhead->sacl = cpu_to_le32(pos);
|
||||
pos += aclsz;
|
||||
pnhead->control |= SE_SACL_PRESENT;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* inherit or redefine owner
|
||||
*/
|
||||
if (!usid) {
|
||||
offowner = le32_to_cpu(pphead->owner);
|
||||
usid = (const SID*)&parentattr[offowner];
|
||||
}
|
||||
usidsz = sid_size(usid);
|
||||
memcpy(&newattr[pos],usid,usidsz);
|
||||
pnhead->owner = cpu_to_le32(pos);
|
||||
pos += usidsz;
|
||||
/*
|
||||
* inherit or redefine group
|
||||
*/
|
||||
if (!gsid) {
|
||||
offgroup = le32_to_cpu(pphead->group);
|
||||
gsid = (const SID*)&parentattr[offgroup];
|
||||
}
|
||||
gsidsz = sid_size(gsid);
|
||||
memcpy(&newattr[pos],gsid,gsidsz);
|
||||
pnhead->group = cpu_to_le32(pos);
|
||||
pos += usidsz;
|
||||
securid = setsecurityattr(scx->vol,
|
||||
(SECURITY_DESCRIPTOR_RELATIVE*)newattr, pos);
|
||||
} else
|
||||
securid = cpu_to_le32(0);
|
||||
return (securid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get an inherited security id
|
||||
*
|
||||
* For Windows compatibility, the normal initial permission setting
|
||||
* may be inherited from the parent directory instead of being
|
||||
* defined by the creation arguments.
|
||||
*
|
||||
* The following creates an inherited id for that purpose.
|
||||
*
|
||||
* Note : the owner and group of parent directory are also
|
||||
* inherited (which is not the case on Windows) if no user mapping
|
||||
* is defined.
|
||||
*
|
||||
* Returns the inherited id, or zero if not possible (eg on NTFS 1.x)
|
||||
*/
|
||||
|
||||
le32 ntfs_inherited_id(struct SECURITY_CONTEXT *scx,
|
||||
const char *dir_path, ntfs_inode *dir_ni, BOOL fordir)
|
||||
{
|
||||
struct CACHED_PERMISSIONS *cached;
|
||||
char *parentattr;
|
||||
le32 securid;
|
||||
|
||||
securid = cpu_to_le32(0);
|
||||
cached = (struct CACHED_PERMISSIONS*)NULL;
|
||||
/*
|
||||
* Try to get inherited id from cache
|
||||
*/
|
||||
if (test_nino_flag(dir_ni, v3_Extensions)
|
||||
&& dir_ni->security_id) {
|
||||
cached = fetch_cache(scx, dir_ni);
|
||||
if (cached)
|
||||
securid = (fordir ? cached->inh_dirid
|
||||
: cached->inh_fileid);
|
||||
}
|
||||
/*
|
||||
* Not cached or not available in cache, compute it all
|
||||
* Note : if parent directory has no id, it is not cacheable
|
||||
*/
|
||||
if (!securid) {
|
||||
parentattr = getsecurityattr(scx->vol, dir_path, dir_ni);
|
||||
if (parentattr) {
|
||||
securid = build_inherited_id(scx,
|
||||
parentattr,
|
||||
dir_ni, fordir);
|
||||
free(parentattr);
|
||||
/*
|
||||
* Store the result into cache for further use
|
||||
*/
|
||||
if (securid) {
|
||||
cached = fetch_cache(scx, dir_ni);
|
||||
if (cached) {
|
||||
if (fordir)
|
||||
cached->inh_dirid = securid;
|
||||
else
|
||||
cached->inh_fileid = securid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (securid);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get a single mapping item from buffer
|
||||
|
@ -3509,7 +3739,7 @@ static int ntfs_default_mapping(struct SECURITY_CONTEXT *scx)
|
|||
res = -1;
|
||||
ni = ntfs_pathname_to_inode(scx->vol, NULL, "/.");
|
||||
if (ni) {
|
||||
securattr = getsecurityattr(scx,"/.",ni);
|
||||
securattr = getsecurityattr(scx->vol,"/.",ni);
|
||||
if (securattr) {
|
||||
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
|
||||
usid = (SID*)&securattr[le32_to_cpu(phead->owner)];
|
||||
|
@ -3914,7 +4144,7 @@ BOOL ntfs_get_file_security(struct SECURITY_API *scapi,
|
|||
if (scapi && (scapi->magic == MAGIC_API)) {
|
||||
ni = ntfs_pathname_to_inode(scapi->security.vol, NULL, path);
|
||||
if (ni) {
|
||||
attr = getsecurityattr(&scapi->security, path, ni);
|
||||
attr = getsecurityattr(scapi->security.vol, path, ni);
|
||||
if (attr) {
|
||||
ok = feedsecurityattr(attr,selection,
|
||||
buf,buflen,psize);
|
||||
|
@ -3969,7 +4199,7 @@ BOOL ntfs_set_file_security(struct SECURITY_API *scapi,
|
|||
ni = ntfs_pathname_to_inode(scapi->security.vol,
|
||||
NULL, path);
|
||||
if (ni) {
|
||||
oldattr = getsecurityattr(&scapi->security,
|
||||
oldattr = getsecurityattr(scapi->security.vol,
|
||||
path, ni);
|
||||
if (oldattr) {
|
||||
ok = mergesecurityattr(
|
||||
|
|
|
@ -207,24 +207,25 @@ static long ntfs_get_nr_free_mft_records(ntfs_volume *vol)
|
|||
}
|
||||
|
||||
/*
|
||||
* Fill a security context as needed by security fonctions
|
||||
* returns TRUE if Ok
|
||||
* FALSE if there is no user mapping. This is not an error
|
||||
* Fill a security context as needed by security functions
|
||||
* returns TRUE if there is a user mapping,
|
||||
* FALSE if there is none
|
||||
* This is not an error and the context is filled anyway,
|
||||
* it is used for implicit Windows-like inheritance
|
||||
*/
|
||||
|
||||
static BOOL ntfs_fuse_fill_security_context(struct SECURITY_CONTEXT *scx)
|
||||
{
|
||||
struct fuse_context *fusecontext;
|
||||
|
||||
if (ctx->security.usermapping) {
|
||||
scx->vol = ctx->vol;
|
||||
scx->usermapping = ctx->security.usermapping;
|
||||
scx->groupmapping = ctx->security.groupmapping;
|
||||
scx->pseccache = &ctx->seccache;
|
||||
fusecontext = fuse_get_context();
|
||||
scx->uid = fusecontext->uid;
|
||||
scx->gid = fusecontext->gid;
|
||||
}
|
||||
scx->vol = ctx->vol;
|
||||
scx->usermapping = ctx->security.usermapping;
|
||||
scx->groupmapping = ctx->security.groupmapping;
|
||||
scx->pseccache = &ctx->seccache;
|
||||
fusecontext = fuse_get_context();
|
||||
scx->uid = fusecontext->uid;
|
||||
scx->gid = fusecontext->gid;
|
||||
|
||||
return (ctx->security.usermapping != (struct MAPPING*)NULL);
|
||||
}
|
||||
|
||||
|
@ -380,6 +381,8 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
|
|||
struct SECURITY_CONTEXT security;
|
||||
|
||||
vol = ctx->vol;
|
||||
if (!strcmp(org_path,"/dump"))
|
||||
dumpall(vol);
|
||||
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
|
||||
if (stream_name_len < 0)
|
||||
return stream_name_len;
|
||||
|
@ -1002,10 +1005,14 @@ static int ntfs_fuse_create(const char *org_path, dev_t typemode, dev_t dev,
|
|||
* be lost when creation is applied if user
|
||||
* mapping has been defined
|
||||
*/
|
||||
if (test_nino_flag(dir_ni, v3_Extensions))
|
||||
securid = dir_ni->security_id;
|
||||
if (ctx->inherit || !ctx->security.usermapping)
|
||||
securid = ntfs_inherited_id(&security, dir_path,
|
||||
dir_ni, S_ISDIR(type));
|
||||
else
|
||||
securid = cpu_to_le32(0);
|
||||
if (test_nino_flag(dir_ni, v3_Extensions))
|
||||
securid = dir_ni->security_id;
|
||||
else
|
||||
securid = cpu_to_le32(0);
|
||||
/* Create object specified in @type. */
|
||||
switch (type) {
|
||||
case S_IFCHR:
|
||||
|
@ -1832,8 +1839,8 @@ static void ntfs_fuse_destroy(void)
|
|||
10 * ctx->seccache->head.s_hops
|
||||
/ ctx->seccache->head.s_reads % 10);
|
||||
}
|
||||
ntfs_close_secure(&security);
|
||||
}
|
||||
ntfs_close_secure(&security);
|
||||
if (ntfs_umount(ctx->vol, FALSE))
|
||||
ntfs_log_perror("Failed to cleanly unmount volume %s",
|
||||
opts.device);
|
||||
|
|
Loading…
Reference in New Issue