diff --git a/daemon/open.c b/daemon/open.c index 2253b8f..c85312b 100644 --- a/daemon/open.c +++ b/daemon/open.c @@ -815,7 +815,7 @@ static int handle_close(nfs41_upcall *upcall) if (args->renamed) { dprintf(1, "removing a renamed file %s\n", name->name); - create_silly_rename(&state->path, name); + create_silly_rename(&state->path, &state->file.fh, name); status = do_nfs41_close(state); if (status) goto out; diff --git a/daemon/setattr.c b/daemon/setattr.c index 7ab950f..babcb35 100644 --- a/daemon/setattr.c +++ b/daemon/setattr.c @@ -223,7 +223,7 @@ static int handle_nfs41_rename(setattr_upcall_args *args) path_fh_init(&dst_dir, &dst_path); fh_copy(&dst_dir.fh, &state->parent.fh); - create_silly_rename(&dst_path, &dst_name); + create_silly_rename(&dst_path, &state->file.fh, &dst_name); dprintf(1, "silly rename: %s -> %s\n", src_name->name, dst_name.name); /* break any delegations and truncate before silly rename */ diff --git a/daemon/util.c b/daemon/util.c index f8ce1e4..41c18a1 100644 --- a/daemon/util.c +++ b/daemon/util.c @@ -23,6 +23,7 @@ #include #include #include +#include /* for Crypt*() functions */ #include "daemon_debug.h" #include "util.h" @@ -349,35 +350,72 @@ void path_fh_copy( fh_copy(&dst->fh, &src->fh); } -/* DWORD MAX_DWORD = 4294967295 -- max string for the timestamp */ int create_silly_rename( IN nfs41_abs_path *path, + IN const nfs41_fh *fh, OUT nfs41_component *silly) { + HCRYPTPROV context; + HCRYPTHASH hash; + PBYTE buffer; + DWORD length; const char *end = path->path + NFS41_MAX_PATH_LEN; - char name[NFS41_MAX_COMPONENT_LEN+1], *tmp, stime[13]; - int status = NO_ERROR; - const DWORD ntime = GetTickCount(); + const unsigned short extra_len = 2 + 16; //md5 is 16 + char name[NFS41_MAX_COMPONENT_LEN+1]; + unsigned char fhmd5[17] = { 0 }; + char *tmp; + int status = NO_ERROR, i; - StringCchPrintf(stime, 13, "%u", ntime); - if (path->len + 13 >= NFS41_MAX_PATH_LEN) { + if (path->len + extra_len >= NFS41_MAX_PATH_LEN) { status = ERROR_BUFFER_OVERFLOW; goto out; } + /* set up the md5 hash generator */ + if (!CryptAcquireContext(&context, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + status = GetLastError(); + eprintf("CryptAcquireContext() failed with %d\n", status); + goto out; + } + if (!CryptCreateHash(context, CALG_MD5, 0, 0, &hash)) { + status = GetLastError(); + eprintf("CryptCreateHash() failed with %d\n", status); + goto out_context; + } + + if (!CryptHashData(hash, (const BYTE*)fh->fh, (DWORD)fh->len, 0)) { + status = GetLastError(); + eprintf("CryptHashData() failed with %d\n", status); + goto out_hash; + } + + /* extract the hash buffer */ + buffer = (PBYTE)fhmd5; + length = 16; + if (!CryptGetHashParam(hash, HP_HASHVAL, buffer, &length, 0)) { + status = GetLastError(); + eprintf("CryptGetHashParam(val) failed with %d\n", status); + goto out_hash; + } + last_component(path->path, path->path + path->len, silly); - if (silly->len + 13 > NFS41_MAX_COMPONENT_LEN) { - status = ERROR_BUFFER_OVERFLOW; - goto out; - } - StringCchCopyNA(name, NFS41_MAX_COMPONENT_LEN+1, silly->name, silly->len); tmp = (char*)silly->name; - StringCchPrintf(tmp, end - tmp, ".%s.%s", name, stime); + StringCchPrintf(tmp, end - tmp, ".%s.", name); + tmp += silly->len + 2; - path->len = (unsigned short)strlen(path->path); - silly->len = (unsigned short)strlen(silly->name); + for (i = 0; i < 16; i++, tmp++) + StringCchPrintf(tmp, end - tmp, "%x", fhmd5[i]); + + path->len = path->len + extra_len; + silly->len = silly->len + extra_len; + +out_hash: + CryptDestroyHash(hash); +out_context: + CryptReleaseContext(context, 0); out: return status; -} \ No newline at end of file +} diff --git a/daemon/util.h b/daemon/util.h index 60d3ea0..c4f8e5e 100644 --- a/daemon/util.h +++ b/daemon/util.h @@ -165,6 +165,7 @@ static __inline void nfstime_abs( int create_silly_rename( IN nfs41_abs_path *path, + IN const nfs41_fh *fh, OUT nfs41_component *silly); bool_t multi_addr_find(