зеркало из https://github.com/mono/corefx.git
Merge Master into 2019-08 (#371)
We bumped incorrectly a few times, so in order to make it right again, merge master into 2019-08
This commit is contained in:
Родитель
8524b2bfca
Коммит
ce3063888d
|
@ -15,9 +15,14 @@ internal static partial class Interop
|
|||
{
|
||||
private readonly Status _minorStatus;
|
||||
|
||||
public Status MajorStatus
|
||||
{
|
||||
get { return (Status)HResult; }
|
||||
}
|
||||
|
||||
public Status MinorStatus
|
||||
{
|
||||
get { return _minorStatus;}
|
||||
get { return _minorStatus; }
|
||||
}
|
||||
|
||||
public GssApiException(string message) : base(message)
|
||||
|
@ -25,20 +30,44 @@ internal static partial class Interop
|
|||
}
|
||||
|
||||
public GssApiException(Status majorStatus, Status minorStatus)
|
||||
: base(GetGssApiDisplayStatus(majorStatus, minorStatus))
|
||||
: base(GetGssApiDisplayStatus(majorStatus, minorStatus, null))
|
||||
{
|
||||
HResult = (int)majorStatus;
|
||||
_minorStatus = minorStatus;
|
||||
}
|
||||
|
||||
private static string GetGssApiDisplayStatus(Status majorStatus, Status minorStatus)
|
||||
public GssApiException(Status majorStatus, Status minorStatus, string helpText)
|
||||
: base(GetGssApiDisplayStatus(majorStatus, minorStatus, helpText))
|
||||
{
|
||||
HResult = (int)majorStatus;
|
||||
_minorStatus = minorStatus;
|
||||
}
|
||||
|
||||
private static string GetGssApiDisplayStatus(Status majorStatus, Status minorStatus, string helpText)
|
||||
{
|
||||
string majorError = GetGssApiDisplayStatus(majorStatus, isMinor: false);
|
||||
string minorError = GetGssApiDisplayStatus(minorStatus, isMinor: true);
|
||||
string errorMessage;
|
||||
|
||||
return (majorError != null && minorError != null) ?
|
||||
SR.Format(SR.net_gssapi_operation_failed_detailed, majorError, minorError) :
|
||||
SR.Format(SR.net_gssapi_operation_failed, majorStatus.ToString("x"), minorStatus.ToString("x"));
|
||||
if (minorStatus != Status.GSS_S_COMPLETE)
|
||||
{
|
||||
string minorError = GetGssApiDisplayStatus(minorStatus, isMinor: true);
|
||||
errorMessage = (majorError != null && minorError != null) ?
|
||||
SR.Format(SR.net_gssapi_operation_failed_detailed, majorError, minorError) :
|
||||
SR.Format(SR.net_gssapi_operation_failed, majorStatus.ToString("x"), minorStatus.ToString("x"));
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = (majorError != null) ?
|
||||
SR.Format(SR.net_gssapi_operation_failed_detailed_majoronly, majorError) :
|
||||
SR.Format(SR.net_gssapi_operation_failed_majoronly, majorStatus.ToString("x"));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(helpText))
|
||||
{
|
||||
return errorMessage + " " + helpText;
|
||||
}
|
||||
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
private static string GetGssApiDisplayStatus(Status status, bool isMinor)
|
||||
|
@ -60,4 +89,4 @@ internal static partial class Interop
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ internal static partial class Interop
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct GssBuffer : IDisposable
|
||||
{
|
||||
internal UInt64 _length;
|
||||
internal ulong _length;
|
||||
internal IntPtr _data;
|
||||
|
||||
internal int Copy(byte[] destination, int offset)
|
||||
|
@ -66,11 +66,11 @@ internal static partial class Interop
|
|||
#if DEBUG
|
||||
static GssBuffer()
|
||||
{
|
||||
// Verify managed size on both 32-bit and 64-bit matches the PAL_GssBuffer
|
||||
// Verify managed size on both 32-bit and 64-bit matches the PAL_GssBuffer
|
||||
// native struct size, which is also padded on 32-bit.
|
||||
Debug.Assert(Marshal.SizeOf<GssBuffer>() == 16);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,4 +38,4 @@ internal static partial class Interop
|
|||
// No-op that exists to provide a hook for other static constructors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,11 +12,120 @@ internal static partial class Interop
|
|||
{
|
||||
internal static partial class NetSecurityNative
|
||||
{
|
||||
#if ENABLE_GSS
|
||||
#if !ENABLE_GSS
|
||||
internal static void ReleaseGssBuffer(
|
||||
IntPtr bufferPtr,
|
||||
ulong length) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status DisplayMinorStatus(
|
||||
out Status minorStatus,
|
||||
Status statusValue,
|
||||
ref GssBuffer buffer) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status DisplayMajorStatus(
|
||||
out Status minorStatus,
|
||||
Status statusValue,
|
||||
ref GssBuffer buffer) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status ImportUserName(
|
||||
out Status minorStatus,
|
||||
string inputName,
|
||||
int inputNameByteCount,
|
||||
out SafeGssNameHandle outputName) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status ImportPrincipalName(
|
||||
out Status minorStatus,
|
||||
string inputName,
|
||||
int inputNameByteCount,
|
||||
out SafeGssNameHandle outputName) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status ReleaseName(
|
||||
out Status minorStatus,
|
||||
ref IntPtr inputName) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status InitiateCredSpNego(
|
||||
out Status minorStatus,
|
||||
SafeGssNameHandle desiredName,
|
||||
out SafeGssCredHandle outputCredHandle) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status InitiateCredWithPassword(
|
||||
out Status minorStatus,
|
||||
bool isNtlm,
|
||||
SafeGssNameHandle desiredName,
|
||||
string password,
|
||||
int passwordLen,
|
||||
out SafeGssCredHandle outputCredHandle) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status ReleaseCred(
|
||||
out Status minorStatus,
|
||||
ref IntPtr credHandle) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status InitSecContext(
|
||||
out Status minorStatus,
|
||||
SafeGssCredHandle initiatorCredHandle,
|
||||
ref SafeGssContextHandle contextHandle,
|
||||
bool isNtlmOnly,
|
||||
SafeGssNameHandle targetName,
|
||||
uint reqFlags,
|
||||
byte[] inputBytes,
|
||||
int inputLength,
|
||||
ref GssBuffer token,
|
||||
out uint retFlags,
|
||||
out int isNtlmUsed) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status InitSecContext(
|
||||
out Status minorStatus,
|
||||
SafeGssCredHandle initiatorCredHandle,
|
||||
ref SafeGssContextHandle contextHandle,
|
||||
bool isNtlmOnly,
|
||||
IntPtr cbt,
|
||||
int cbtSize,
|
||||
SafeGssNameHandle targetName,
|
||||
uint reqFlags,
|
||||
byte[] inputBytes,
|
||||
int inputLength,
|
||||
ref GssBuffer token,
|
||||
out uint retFlags,
|
||||
out int isNtlmUsed) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status AcceptSecContext(
|
||||
out Status minorStatus,
|
||||
ref SafeGssContextHandle acceptContextHandle,
|
||||
byte[] inputBytes,
|
||||
int inputLength,
|
||||
ref GssBuffer token,
|
||||
out uint retFlags) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status DeleteSecContext(
|
||||
out Status minorStatus,
|
||||
ref IntPtr contextHandle) => throw new PlatformNotSupportedException ();
|
||||
|
||||
internal static Status GetUser(
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle acceptContextHandle,
|
||||
ref GssBuffer token) => throw new PlatformNotSupportedException ();
|
||||
|
||||
private static Status Wrap(
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle contextHandle,
|
||||
bool isEncrypt,
|
||||
byte[] inputBytes,
|
||||
int offset,
|
||||
int count,
|
||||
ref GssBuffer outBuffer) => throw new PlatformNotSupportedException ();
|
||||
|
||||
private static Status Unwrap(
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle contextHandle,
|
||||
byte[] inputBytes,
|
||||
int offset,
|
||||
int count,
|
||||
ref GssBuffer outBuffer) => throw new PlatformNotSupportedException ();
|
||||
#else
|
||||
[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ReleaseGssBuffer")]
|
||||
internal static extern void ReleaseGssBuffer(
|
||||
IntPtr bufferPtr,
|
||||
UInt64 length);
|
||||
ulong length);
|
||||
|
||||
[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DisplayMinorStatus")]
|
||||
internal static extern Status DisplayMinorStatus(
|
||||
|
@ -83,19 +192,42 @@ internal static partial class Interop
|
|||
out uint retFlags,
|
||||
out int isNtlmUsed);
|
||||
|
||||
[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_InitSecContextEx")]
|
||||
internal static extern Status InitSecContext(
|
||||
out Status minorStatus,
|
||||
SafeGssCredHandle initiatorCredHandle,
|
||||
ref SafeGssContextHandle contextHandle,
|
||||
bool isNtlmOnly,
|
||||
IntPtr cbt,
|
||||
int cbtSize,
|
||||
SafeGssNameHandle targetName,
|
||||
uint reqFlags,
|
||||
byte[] inputBytes,
|
||||
int inputLength,
|
||||
ref GssBuffer token,
|
||||
out uint retFlags,
|
||||
out int isNtlmUsed);
|
||||
|
||||
[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_AcceptSecContext")]
|
||||
internal static extern Status AcceptSecContext(
|
||||
out Status minorStatus,
|
||||
ref SafeGssContextHandle acceptContextHandle,
|
||||
byte[] inputBytes,
|
||||
int inputLength,
|
||||
ref GssBuffer token);
|
||||
ref GssBuffer token,
|
||||
out uint retFlags);
|
||||
|
||||
[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DeleteSecContext")]
|
||||
internal static extern Status DeleteSecContext(
|
||||
out Status minorStatus,
|
||||
ref IntPtr contextHandle);
|
||||
|
||||
[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_GetUser")]
|
||||
internal static extern Status GetUser(
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle acceptContextHandle,
|
||||
ref GssBuffer token);
|
||||
|
||||
[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_Wrap")]
|
||||
private static extern Status Wrap(
|
||||
out Status minorStatus,
|
||||
|
@ -114,6 +246,7 @@ internal static partial class Interop
|
|||
int offset,
|
||||
int count,
|
||||
ref GssBuffer outBuffer);
|
||||
#endif
|
||||
|
||||
internal static Status WrapBuffer(
|
||||
out Status minorStatus,
|
||||
|
@ -145,117 +278,33 @@ internal static partial class Interop
|
|||
|
||||
return Unwrap(out minorStatus, contextHandle, inputBytes, offset, count, ref outBuffer);
|
||||
}
|
||||
#else
|
||||
internal static void ReleaseGssBuffer (
|
||||
IntPtr bufferPtr,
|
||||
UInt64 length) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status DisplayMinorStatus (
|
||||
out Status minorStatus,
|
||||
Status statusValue,
|
||||
ref GssBuffer buffer) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status DisplayMajorStatus (
|
||||
out Status minorStatus,
|
||||
Status statusValue,
|
||||
ref GssBuffer buffer) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status ImportUserName (
|
||||
out Status minorStatus,
|
||||
string inputName,
|
||||
int inputNameByteCount,
|
||||
out SafeGssNameHandle outputName) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status ImportPrincipalName (
|
||||
out Status minorStatus,
|
||||
string inputName,
|
||||
int inputNameByteCount,
|
||||
out SafeGssNameHandle outputName) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status ReleaseName (
|
||||
out Status minorStatus,
|
||||
ref IntPtr inputName) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status InitiateCredSpNego (
|
||||
out Status minorStatus,
|
||||
SafeGssNameHandle desiredName,
|
||||
out SafeGssCredHandle outputCredHandle) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status InitiateCredWithPassword (
|
||||
out Status minorStatus,
|
||||
bool isNtlm,
|
||||
SafeGssNameHandle desiredName,
|
||||
string password,
|
||||
int passwordLen,
|
||||
out SafeGssCredHandle outputCredHandle) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status ReleaseCred (
|
||||
out Status minorStatus,
|
||||
ref IntPtr credHandle) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status InitSecContext (
|
||||
out Status minorStatus,
|
||||
SafeGssCredHandle initiatorCredHandle,
|
||||
ref SafeGssContextHandle contextHandle,
|
||||
bool isNtlmOnly,
|
||||
SafeGssNameHandle targetName,
|
||||
uint reqFlags,
|
||||
byte[] inputBytes,
|
||||
int inputLength,
|
||||
ref GssBuffer token,
|
||||
out uint retFlags,
|
||||
out int isNtlmUsed) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status AcceptSecContext (
|
||||
out Status minorStatus,
|
||||
ref SafeGssContextHandle acceptContextHandle,
|
||||
byte[] inputBytes,
|
||||
int inputLength,
|
||||
ref GssBuffer token) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status DeleteSecContext (
|
||||
out Status minorStatus,
|
||||
ref IntPtr contextHandle) => throw new NotSupportedException ();
|
||||
|
||||
static Status Wrap(
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle contextHandle,
|
||||
bool isEncrypt,
|
||||
byte[] inputBytes,
|
||||
int offset,
|
||||
int count,
|
||||
ref GssBuffer outBuffer) => throw new NotSupportedException ();
|
||||
|
||||
static Status Unwrap (
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle contextHandle,
|
||||
byte[] inputBytes,
|
||||
int offset,
|
||||
int count,
|
||||
ref GssBuffer outBuffer) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status WrapBuffer (
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle contextHandle,
|
||||
bool isEncrypt,
|
||||
byte[] inputBytes,
|
||||
int offset,
|
||||
int count,
|
||||
ref GssBuffer outBuffer) => throw new NotSupportedException ();
|
||||
|
||||
internal static Status UnwrapBuffer (
|
||||
out Status minorStatus,
|
||||
SafeGssContextHandle contextHandle,
|
||||
byte[] inputBytes,
|
||||
int offset,
|
||||
int count,
|
||||
ref GssBuffer outBuffer) => throw new NotSupportedException ();
|
||||
#endif
|
||||
// https://www.gnu.org/software/gss/reference/gss.pdf Page 65
|
||||
internal const int GSS_C_ROUTINE_ERROR_OFFSET = 16;
|
||||
|
||||
// https://www.gnu.org/software/gss/reference/gss.pdf Page 9
|
||||
internal enum Status : uint
|
||||
{
|
||||
GSS_S_COMPLETE = 0,
|
||||
GSS_S_CONTINUE_NEEDED = 1
|
||||
GSS_S_CONTINUE_NEEDED = 1,
|
||||
GSS_S_BAD_MECH = 1 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_BAD_NAME = 2 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_BAD_NAMETYPE = 3 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_BAD_BINDINGS = 4 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_BAD_STATUS = 5 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_BAD_SIG = 6 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_NO_CRED = 7 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_NO_CONTEXT = 8 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_DEFECTIVE_TOKEN = 9 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_DEFECTIVE_CREDENTIAL = 10 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_CREDENTIALS_EXPIRED = 11 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_CONTEXT_EXPIRED = 12 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_FAILURE = 13 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_BAD_QOP = 14 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_UNAUTHORIZED = 15 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_UNAVAILABLE = 16 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_DUPLICATE_ELEMENT = 17 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
GSS_S_NAME_NOT_MN = 18 << GSS_C_ROUTINE_ERROR_OFFSET,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
@ -276,4 +325,4 @@ internal static partial class Interop
|
|||
GSS_C_DELEG_POLICY_FLAG = 0x8000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -146,4 +146,4 @@ namespace Microsoft.Win32.SafeHandles
|
|||
return status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -413,4 +413,4 @@ namespace System.Net.Security
|
|||
return resultSize + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -77,4 +77,4 @@ namespace System.Net.Security
|
|||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -97,6 +97,7 @@ BEGIN_EXTERN_C
|
|||
|
||||
typedef int errno_t;
|
||||
|
||||
#ifndef HAVE_MEMCPY_S
|
||||
inline static errno_t memcpy_s(void* dst, size_t sizeInBytes, const void* src, size_t count)
|
||||
{
|
||||
if (count > 0)
|
||||
|
@ -124,5 +125,6 @@ inline static errno_t memcpy_s(void* dst, size_t sizeInBytes, const void* src, s
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
END_EXTERN_C
|
||||
|
|
|
@ -1257,15 +1257,30 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd)
|
|||
int ret;
|
||||
struct stat_ sourceStat;
|
||||
bool copied = false;
|
||||
#if HAVE_SENDFILE_4
|
||||
// If sendfile is available (Linux), try to use it, as the whole copy
|
||||
// can be performed in the kernel, without lots of unnecessary copying.
|
||||
|
||||
// First, stat the source file.
|
||||
while ((ret = fstat_(inFd, &sourceStat)) < 0 && errno == EINTR);
|
||||
if (ret != 0)
|
||||
{
|
||||
// If we can't stat() it, then we likely don't have permission to read it.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Copy permissions. This fchmod() needs to happen prior to writing anything into
|
||||
// the file to avoid possibly leaking any private data.
|
||||
while ((ret = fchmod(outFd, sourceStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) < 0 && errno == EINTR);
|
||||
#if !TARGET_ANDROID
|
||||
// On Android, we are not allowed to modify permissions, but the copy should still succeed;
|
||||
// see https://github.com/mono/mono/issues/17133 for details.
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SENDFILE_4
|
||||
// If sendfile is available (Linux), try to use it, as the whole copy
|
||||
// can be performed in the kernel, without lots of unnecessary copying.
|
||||
|
||||
// On 32-bit, if you use 64-bit offsets, the last argument of `sendfile' will be a
|
||||
// `size_t' a 32-bit integer while the `st_size' field of the stat structure will be off64_t.
|
||||
|
@ -1313,37 +1328,30 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd)
|
|||
// from the source file. First copy the file times.
|
||||
// If futimes nor futimes are available on this platform, file times will
|
||||
// not be copied over.
|
||||
while ((ret = fstat_(inFd, &sourceStat)) < 0 && errno == EINTR);
|
||||
if (ret == 0)
|
||||
{
|
||||
#if HAVE_FUTIMENS
|
||||
// futimens is prefered because it has a higher resolution.
|
||||
struct timespec origTimes[2];
|
||||
origTimes[0].tv_sec = (time_t)sourceStat.st_atime;
|
||||
origTimes[0].tv_nsec = ST_ATIME_NSEC(&sourceStat);
|
||||
origTimes[1].tv_sec = (time_t)sourceStat.st_mtime;
|
||||
origTimes[1].tv_nsec = ST_MTIME_NSEC(&sourceStat);
|
||||
while ((ret = futimens(outFd, origTimes)) < 0 && errno == EINTR);
|
||||
// futimens is prefered because it has a higher resolution.
|
||||
struct timespec origTimes[2];
|
||||
origTimes[0].tv_sec = (time_t)sourceStat.st_atime;
|
||||
origTimes[0].tv_nsec = ST_ATIME_NSEC(&sourceStat);
|
||||
origTimes[1].tv_sec = (time_t)sourceStat.st_mtime;
|
||||
origTimes[1].tv_nsec = ST_MTIME_NSEC(&sourceStat);
|
||||
while ((ret = futimens(outFd, origTimes)) < 0 && errno == EINTR);
|
||||
#elif HAVE_FUTIMES
|
||||
struct timeval origTimes[2];
|
||||
origTimes[0].tv_sec = sourceStat.st_atime;
|
||||
origTimes[0].tv_usec = ST_ATIME_NSEC(&sourceStat) / 1000;
|
||||
origTimes[1].tv_sec = sourceStat.st_mtime;
|
||||
origTimes[1].tv_usec = ST_MTIME_NSEC(&sourceStat) / 1000;
|
||||
while ((ret = futimes(outFd, origTimes)) < 0 && errno == EINTR);
|
||||
struct timeval origTimes[2];
|
||||
origTimes[0].tv_sec = sourceStat.st_atime;
|
||||
origTimes[0].tv_usec = ST_ATIME_NSEC(&sourceStat) / 1000;
|
||||
origTimes[1].tv_sec = sourceStat.st_mtime;
|
||||
origTimes[1].tv_usec = ST_MTIME_NSEC(&sourceStat) / 1000;
|
||||
while ((ret = futimes(outFd, origTimes)) < 0 && errno == EINTR);
|
||||
#endif
|
||||
}
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Then copy permissions.
|
||||
while ((ret = fchmod(outFd, sourceStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) < 0 && errno == EINTR);
|
||||
#if !TARGET_ANDROID
|
||||
// On Android, the copy should still succeed even if copying the file times didn't.
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
#endif // HAVE_FCOPYFILE
|
||||
|
|
|
@ -816,6 +816,7 @@ static int32_t GetIPv4PacketInformation(struct cmsghdr* controlMessage, struct I
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef IPV6_PKTINFO
|
||||
static int32_t GetIPv6PacketInformation(struct cmsghdr* controlMessage, struct IPPacketInformation* packetInfo)
|
||||
{
|
||||
assert(controlMessage != NULL);
|
||||
|
@ -834,6 +835,7 @@ static int32_t GetIPv6PacketInformation(struct cmsghdr* controlMessage, struct I
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct cmsghdr* GET_CMSG_NXTHDR(struct msghdr* mhdr, struct cmsghdr* cmsg)
|
||||
{
|
||||
|
@ -1474,9 +1476,11 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionName, int32_t socketO
|
|||
*optName = SO_DEBUG;
|
||||
return true;
|
||||
|
||||
#ifdef SO_ACCEPTCONN
|
||||
case SocketOptionName_SO_ACCEPTCONN:
|
||||
*optName = SO_ACCEPTCONN;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
case SocketOptionName_SO_REUSEADDR:
|
||||
*optName = SO_REUSEADDR;
|
||||
|
@ -1638,9 +1642,11 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionName, int32_t socketO
|
|||
|
||||
// case SocketOptionName_SO_IPV6_PROTECTION_LEVEL:
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
case SocketOptionName_SO_IPV6_V6ONLY:
|
||||
*optName = IPV6_V6ONLY;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef IPV6_RECVPKTINFO
|
||||
case SocketOptionName_SO_IP_PKTINFO:
|
||||
|
@ -1901,9 +1907,11 @@ static bool TryConvertProtocolTypePalToPlatform(int32_t palProtocolType, int* pl
|
|||
*platformProtocolType = IPPROTO_UDP;
|
||||
return true;
|
||||
|
||||
#ifdef IPPROTO_ICMPV6
|
||||
case ProtocolType_PT_ICMPV6:
|
||||
*platformProtocolType = IPPROTO_ICMPV6;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
default:
|
||||
*platformProtocolType = (int)palProtocolType;
|
||||
|
|
|
@ -111,7 +111,7 @@ static uint32_t NetSecurityNative_DisplayStatus(uint32_t* minorStatus,
|
|||
assert(minorStatus != NULL);
|
||||
assert(outBuffer != NULL);
|
||||
|
||||
uint32_t messageContext;
|
||||
uint32_t messageContext = 0; // Must initialize to 0 before calling gss_display_status.
|
||||
GssBuffer gssBuffer = {.length = 0, .value = NULL};
|
||||
uint32_t majorStatus =
|
||||
gss_display_status(minorStatus, statusValue, statusType, GSS_C_NO_OID, &messageContext, &gssBuffer);
|
||||
|
@ -154,19 +154,36 @@ uint32_t NetSecurityNative_ImportPrincipalName(uint32_t* minorStatus,
|
|||
assert(outputName != NULL);
|
||||
assert(*outputName == NULL);
|
||||
|
||||
gss_OID nameType;
|
||||
|
||||
if (strchr(inputName, '/') != NULL)
|
||||
// Principal name will usually be in the form SERVICE/HOST. But SPNEGO protocol prefers
|
||||
// GSS_C_NT_HOSTBASED_SERVICE format. That format uses '@' separator instead of '/' between
|
||||
// service name and host name. So convert input string into that format.
|
||||
char* ptrSlash = memchr(inputName, '/', inputNameLen);
|
||||
char* inputNameCopy = NULL;
|
||||
if (ptrSlash != NULL)
|
||||
{
|
||||
nameType = GSS_KRB5_NT_PRINCIPAL_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
nameType = GSS_C_NT_HOSTBASED_SERVICE;
|
||||
inputNameCopy = (char*) malloc(inputNameLen);
|
||||
if (inputNameCopy != NULL)
|
||||
{
|
||||
memcpy(inputNameCopy, inputName, inputNameLen);
|
||||
inputNameCopy[ptrSlash - inputName] = '@';
|
||||
inputName = inputNameCopy;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minorStatus = 0;
|
||||
return GSS_S_BAD_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
GssBuffer inputNameBuffer = {.length = inputNameLen, .value = inputName};
|
||||
return gss_import_name(minorStatus, &inputNameBuffer, nameType, outputName);
|
||||
uint32_t result = gss_import_name(minorStatus, &inputNameBuffer, GSS_C_NT_HOSTBASED_SERVICE, outputName);
|
||||
|
||||
if (inputNameCopy != NULL)
|
||||
{
|
||||
free(inputNameCopy);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t NetSecurityNative_InitSecContext(uint32_t* minorStatus,
|
||||
|
@ -180,6 +197,35 @@ uint32_t NetSecurityNative_InitSecContext(uint32_t* minorStatus,
|
|||
PAL_GssBuffer* outBuffer,
|
||||
uint32_t* retFlags,
|
||||
int32_t* isNtlmUsed)
|
||||
{
|
||||
return NetSecurityNative_InitSecContextEx(minorStatus,
|
||||
claimantCredHandle,
|
||||
contextHandle,
|
||||
isNtlm,
|
||||
NULL,
|
||||
0,
|
||||
targetName,
|
||||
reqFlags,
|
||||
inputBytes,
|
||||
inputLength,
|
||||
outBuffer,
|
||||
retFlags,
|
||||
isNtlmUsed);
|
||||
}
|
||||
|
||||
uint32_t NetSecurityNative_InitSecContextEx(uint32_t* minorStatus,
|
||||
GssCredId* claimantCredHandle,
|
||||
GssCtxId** contextHandle,
|
||||
uint32_t isNtlm,
|
||||
void* cbt,
|
||||
int32_t cbtSize,
|
||||
GssName* targetName,
|
||||
uint32_t reqFlags,
|
||||
uint8_t* inputBytes,
|
||||
uint32_t inputLength,
|
||||
PAL_GssBuffer* outBuffer,
|
||||
uint32_t* retFlags,
|
||||
int32_t* isNtlmUsed)
|
||||
{
|
||||
assert(minorStatus != NULL);
|
||||
assert(contextHandle != NULL);
|
||||
|
@ -189,12 +235,13 @@ uint32_t NetSecurityNative_InitSecContext(uint32_t* minorStatus,
|
|||
assert(outBuffer != NULL);
|
||||
assert(retFlags != NULL);
|
||||
assert(isNtlmUsed != NULL);
|
||||
assert(inputBytes != NULL || inputLength == 0);
|
||||
assert(cbt != NULL || cbtSize == 0);
|
||||
|
||||
// Note: claimantCredHandle can be null
|
||||
// Note: *contextHandle is null only in the first call and non-null in the subsequent calls
|
||||
|
||||
#if HAVE_GSS_SPNEGO_MECHANISM
|
||||
gss_OID krbMech = GSS_KRB5_MECHANISM;
|
||||
gss_OID desiredMech;
|
||||
if (isNtlm)
|
||||
{
|
||||
|
@ -204,9 +251,8 @@ uint32_t NetSecurityNative_InitSecContext(uint32_t* minorStatus,
|
|||
{
|
||||
desiredMech = GSS_SPNEGO_MECHANISM;
|
||||
}
|
||||
|
||||
gss_OID krbMech = GSS_KRB5_MECHANISM;
|
||||
#else
|
||||
gss_OID krbMech = (gss_OID)(unsigned long)gss_mech_krb5;
|
||||
gss_OID_desc gss_mech_OID_desc;
|
||||
if (isNtlm)
|
||||
{
|
||||
|
@ -218,14 +264,20 @@ uint32_t NetSecurityNative_InitSecContext(uint32_t* minorStatus,
|
|||
}
|
||||
|
||||
gss_OID desiredMech = &gss_mech_OID_desc;
|
||||
gss_OID krbMech = gss_mech_krb5;
|
||||
#endif
|
||||
|
||||
*isNtlmUsed = 1;
|
||||
GssBuffer inputToken = {.length = inputLength, .value = inputBytes};
|
||||
GssBuffer gssBuffer = {.length = 0, .value = NULL};
|
||||
gss_OID_desc* outmech;
|
||||
|
||||
struct gss_channel_bindings_struct gssCbt;
|
||||
if (cbt != NULL)
|
||||
{
|
||||
memset(&gssCbt, 0, sizeof(struct gss_channel_bindings_struct));
|
||||
gssCbt.application_data.length = (size_t)cbtSize;
|
||||
gssCbt.application_data.value = cbt;
|
||||
}
|
||||
|
||||
uint32_t majorStatus = gss_init_sec_context(minorStatus,
|
||||
claimantCredHandle,
|
||||
contextHandle,
|
||||
|
@ -233,18 +285,14 @@ uint32_t NetSecurityNative_InitSecContext(uint32_t* minorStatus,
|
|||
desiredMech,
|
||||
reqFlags,
|
||||
0,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
(cbt != NULL) ? &gssCbt : GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&inputToken,
|
||||
&outmech,
|
||||
&gssBuffer,
|
||||
retFlags,
|
||||
NULL);
|
||||
|
||||
// Outmech can be null when gssntlmssp lib uses NTLM mechanism
|
||||
if (outmech != NULL && gss_oid_equal(outmech, krbMech) != 0)
|
||||
{
|
||||
*isNtlmUsed = 0;
|
||||
}
|
||||
*isNtlmUsed = (isNtlm || majorStatus != GSS_S_COMPLETE || gss_oid_equal(outmech, krbMech) == 0) ? 1 : 0;
|
||||
|
||||
NetSecurityNative_MoveBuffer(&gssBuffer, outBuffer);
|
||||
return majorStatus;
|
||||
|
@ -254,7 +302,8 @@ uint32_t NetSecurityNative_AcceptSecContext(uint32_t* minorStatus,
|
|||
GssCtxId** contextHandle,
|
||||
uint8_t* inputBytes,
|
||||
uint32_t inputLength,
|
||||
PAL_GssBuffer* outBuffer)
|
||||
PAL_GssBuffer* outBuffer,
|
||||
uint32_t* retFlags)
|
||||
{
|
||||
assert(minorStatus != NULL);
|
||||
assert(contextHandle != NULL);
|
||||
|
@ -273,7 +322,7 @@ uint32_t NetSecurityNative_AcceptSecContext(uint32_t* minorStatus,
|
|||
NULL,
|
||||
NULL,
|
||||
&gssBuffer,
|
||||
0,
|
||||
retFlags,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
|
@ -281,6 +330,44 @@ uint32_t NetSecurityNative_AcceptSecContext(uint32_t* minorStatus,
|
|||
return majorStatus;
|
||||
}
|
||||
|
||||
uint32_t NetSecurityNative_GetUser(uint32_t* minorStatus,
|
||||
GssCtxId* contextHandle,
|
||||
PAL_GssBuffer* outBuffer)
|
||||
{
|
||||
assert(minorStatus != NULL);
|
||||
assert(contextHandle != NULL);
|
||||
assert(outBuffer != NULL);
|
||||
|
||||
gss_name_t srcName = GSS_C_NO_NAME;
|
||||
|
||||
uint32_t majorStatus = gss_inquire_context(minorStatus,
|
||||
contextHandle,
|
||||
&srcName,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (majorStatus == GSS_S_COMPLETE)
|
||||
{
|
||||
GssBuffer gssBuffer = {.length = 0, .value = NULL};
|
||||
majorStatus = gss_display_name(minorStatus, srcName, &gssBuffer, NULL);
|
||||
if (majorStatus == GSS_S_COMPLETE)
|
||||
{
|
||||
NetSecurityNative_MoveBuffer(&gssBuffer, outBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (srcName != NULL)
|
||||
{
|
||||
majorStatus = gss_release_name(minorStatus, &srcName);
|
||||
}
|
||||
|
||||
return majorStatus;
|
||||
}
|
||||
|
||||
uint32_t NetSecurityNative_ReleaseCred(uint32_t* minorStatus, GssCredId** credHandle)
|
||||
{
|
||||
assert(minorStatus != NULL);
|
||||
|
@ -416,4 +503,37 @@ uint32_t NetSecurityNative_InitiateCredWithPassword(uint32_t* minorStatus,
|
|||
{
|
||||
return NetSecurityNative_AcquireCredWithPassword(
|
||||
minorStatus, isNtlm, desiredName, password, passwdLen, GSS_C_INITIATE, outputCredHandle);
|
||||
}
|
||||
|
||||
uint32_t NetSecurityNative_IsNtlmInstalled()
|
||||
{
|
||||
#if HAVE_GSS_SPNEGO_MECHANISM
|
||||
gss_OID ntlmOid = GSS_NTLM_MECHANISM;
|
||||
#else
|
||||
gss_OID ntlmOid = &gss_mech_ntlm_OID_desc;
|
||||
#endif
|
||||
|
||||
uint32_t majorStatus;
|
||||
uint32_t minorStatus;
|
||||
gss_OID_set mechSet;
|
||||
gss_OID_desc oid;
|
||||
uint32_t foundNtlm = 0;
|
||||
|
||||
majorStatus = gss_indicate_mechs(&minorStatus, &mechSet);
|
||||
if (majorStatus == GSS_S_COMPLETE)
|
||||
{
|
||||
for (size_t i = 0; i < mechSet->count; i++)
|
||||
{
|
||||
oid = mechSet->elements[i];
|
||||
if ((oid.length == ntlmOid->length) && (memcmp(oid.elements, ntlmOid->elements, oid.length) == 0))
|
||||
{
|
||||
foundNtlm = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gss_release_oid_set(&minorStatus, &mechSet);
|
||||
}
|
||||
|
||||
return foundNtlm;
|
||||
}
|
|
@ -115,6 +115,20 @@ DLLEXPORT uint32_t NetSecurityNative_InitSecContext(uint32_t* minorStatus,
|
|||
uint32_t* retFlags,
|
||||
int32_t* isNtlmUsed);
|
||||
|
||||
DLLEXPORT uint32_t NetSecurityNative_InitSecContextEx(uint32_t* minorStatus,
|
||||
GssCredId* claimantCredHandle,
|
||||
GssCtxId** contextHandle,
|
||||
uint32_t isNtlm,
|
||||
void* cbt,
|
||||
int32_t cbtSize,
|
||||
GssName* targetName,
|
||||
uint32_t reqFlags,
|
||||
uint8_t* inputBytes,
|
||||
uint32_t inputLength,
|
||||
PAL_GssBuffer* outBuffer,
|
||||
uint32_t* retFlags,
|
||||
int32_t* isNtlmUsed);
|
||||
|
||||
/*
|
||||
Shims the gss_accept_sec_context method.
|
||||
*/
|
||||
|
@ -122,7 +136,8 @@ DLLEXPORT uint32_t NetSecurityNative_AcceptSecContext(uint32_t* minorStatus,
|
|||
GssCtxId** contextHandle,
|
||||
uint8_t* inputBytes,
|
||||
uint32_t inputLength,
|
||||
PAL_GssBuffer* outBuffer);
|
||||
PAL_GssBuffer* outBuffer,
|
||||
uint32_t* retFlags);
|
||||
|
||||
/*
|
||||
|
||||
|
@ -159,4 +174,16 @@ DLLEXPORT uint32_t NetSecurityNative_InitiateCredWithPassword(uint32_t* minorSta
|
|||
GssName* desiredName,
|
||||
char* password,
|
||||
uint32_t passwdLen,
|
||||
GssCredId** outputCredHandle);
|
||||
GssCredId** outputCredHandle);
|
||||
|
||||
/*
|
||||
Shims the gss_indicate_mechs method to detect if NTLM mech is installed.
|
||||
*/
|
||||
DLLEXPORT uint32_t NetSecurityNative_IsNtlmInstalled(void);
|
||||
|
||||
/*
|
||||
Shims gss_inquire_context and gss_display_name to get the remote user principal name.
|
||||
*/
|
||||
DLLEXPORT uint32_t NetSecurityNative_GetUser(uint32_t* minorStatus,
|
||||
GssCtxId* contextHandle,
|
||||
PAL_GssBuffer* outBuffer);
|
|
@ -1145,7 +1145,7 @@ namespace System.Data.SqlClient
|
|||
Task task = null;
|
||||
|
||||
// only send over SQL Batch command if we are not a stored proc and have no parameters and not in batch RPC mode
|
||||
if ((System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
|
||||
if (!BatchRPCMode && (System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
|
||||
{
|
||||
Debug.Assert(!sendToPipe, "trying to send non-context command to pipe");
|
||||
if (null != statistics)
|
||||
|
@ -2534,7 +2534,15 @@ namespace System.Data.SqlClient
|
|||
GetStateObject();
|
||||
Task writeTask = null;
|
||||
|
||||
if ((System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
|
||||
if (BatchRPCMode)
|
||||
{
|
||||
Debug.Assert(inSchema == false, "Batch RPC does not support schema only command beahvior");
|
||||
Debug.Assert(!IsPrepared, "Batch RPC should not be prepared!");
|
||||
Debug.Assert(!IsDirty, "Batch RPC should not be marked as dirty!");
|
||||
Debug.Assert(_SqlRPCBatchArray != null, "RunExecuteReader rpc array not provided");
|
||||
writeTask = _stateObj.Parser.TdsExecuteRPC( _SqlRPCBatchArray, timeout, inSchema, this.Notification, _stateObj, CommandType.StoredProcedure == CommandType, sync: !asyncWrite);
|
||||
}
|
||||
else if ((System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
|
||||
{
|
||||
// Send over SQL Batch command if we are not a stored proc and have no parameters
|
||||
Debug.Assert(!IsUserPrepared, "CommandType.Text with no params should not be prepared!");
|
||||
|
|
|
@ -231,6 +231,8 @@ namespace System.Data.SqlClient
|
|||
destination._sourceVersion = _sourceVersion;
|
||||
destination._sourceColumnNullMapping = _sourceColumnNullMapping;
|
||||
destination._isNullable = _isNullable;
|
||||
destination._parameterName = _parameterName;
|
||||
destination._isNull = _isNull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Data.SqlClient.ManualTesting.Tests
|
||||
{
|
||||
public class SqlAdapterUpdateBatch
|
||||
{
|
||||
[CheckConnStrSetupFact]
|
||||
public void SqlAdapterTest()
|
||||
{
|
||||
string tableName = "BatchDemoTable";
|
||||
try
|
||||
{
|
||||
var createTableQuery = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='BatchDemoTable' AND xtype='U')" +
|
||||
" CREATE TABLE [dbo].[" + tableName + "]([TransactionNumber][int] IDENTITY(1, 1) NOT NULL,[Level] [nvarchar] (50) NOT NULL," +
|
||||
"[Message] [nvarchar] (500) NOT NULL,[EventTime] [datetime]NOT NULL,CONSTRAINT[PK_BatchDemoTable] " +
|
||||
"PRIMARY KEY CLUSTERED([TransactionNumber] ASC)WITH(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF, " +
|
||||
"IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON,FILLFACTOR = 90) ON[PRIMARY]) ON[PRIMARY]";
|
||||
|
||||
using (var connection = new SqlConnection(DataTestUtility.TcpConnStr))
|
||||
using (var cmd = new SqlCommand(createTableQuery, connection))
|
||||
{
|
||||
connection.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
ExecuteNonQueries();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
var dropTableQuery = "DROP TABLE IF EXISTS " + tableName;
|
||||
using (var connection = new SqlConnection(DataTestUtility.TcpConnStr))
|
||||
using (var cmd = new SqlCommand(dropTableQuery, connection))
|
||||
{
|
||||
connection.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class EventInfo
|
||||
{
|
||||
public string Level { get; set; }
|
||||
public string Message { get; set; }
|
||||
public DateTime EventTime { get; set; }
|
||||
|
||||
public EventInfo()
|
||||
{
|
||||
EventTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExecuteNonQueries()
|
||||
{
|
||||
List<EventInfo> entities = new List<EventInfo>
|
||||
{
|
||||
new EventInfo {Level = "L1", Message = "Message 1"},
|
||||
new EventInfo {Level = "L2", Message = "Message 2"},
|
||||
new EventInfo {Level = "L3", Message = "Message 3"},
|
||||
new EventInfo {Level = "L4", Message = "Message 4"},
|
||||
};
|
||||
|
||||
var sql = "INSERT INTO BatchDemoTable(Level, Message, EventTime) VALUES(@Level, @Message, @EventTime)";
|
||||
using (var connection = new SqlConnection(DataTestUtility.TcpConnStr))
|
||||
using (var adapter = new SqlDataAdapter())
|
||||
using (var cmd = new SqlCommand(sql, connection))
|
||||
{
|
||||
cmd.Parameters.Add(new SqlParameter("@Level", System.Data.SqlDbType.NVarChar, 50, "Level"));
|
||||
cmd.Parameters.Add(new SqlParameter("@Message", SqlDbType.NVarChar, 500, "Message"));
|
||||
cmd.Parameters.Add(new SqlParameter("@EventTime", SqlDbType.DateTime, 0, "EventTime"));
|
||||
cmd.UpdatedRowSource = UpdateRowSource.None;
|
||||
|
||||
adapter.InsertCommand = cmd;
|
||||
adapter.UpdateBatchSize = 2;
|
||||
|
||||
adapter.Update(ConvertToTable(entities));
|
||||
}
|
||||
}
|
||||
private static DataTable ConvertToTable(List<EventInfo> entities)
|
||||
{
|
||||
var table = new DataTable(typeof(EventInfo).Name);
|
||||
|
||||
table.Columns.Add("Level", typeof(string));
|
||||
table.Columns.Add("Message", typeof(string));
|
||||
table.Columns.Add("EventTime", typeof(DateTime));
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var row = table.NewRow();
|
||||
row["Level"] = entity.Level;
|
||||
row["Message"] = entity.Message;
|
||||
row["EventTime"] = entity.EventTime;
|
||||
table.Rows.Add(row);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@
|
|||
<Compile Include="SQL\ParameterTest\DateTimeVariantTest.cs" />
|
||||
<Compile Include="SQL\ParameterTest\OutputParameter.cs" />
|
||||
<Compile Include="SQL\ParameterTest\ParametersTest.cs" />
|
||||
<Compile Include="SQL\ParameterTest\SqlAdapterUpdateBatch.cs" />
|
||||
<Compile Include="SQL\ParameterTest\SqlVariantParam.cs" />
|
||||
<Compile Include="SQL\ParameterTest\SteAttribute.cs" />
|
||||
<Compile Include="SQL\ParameterTest\SteParam.cs" />
|
||||
|
|
|
@ -280,6 +280,8 @@ namespace System.IO
|
|||
finally
|
||||
{
|
||||
StaticWatcherRunLoopManager.UnscheduleFromRunLoop(_eventStream);
|
||||
_eventStream.Close();
|
||||
_eventStream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Collections.ObjectModel;
|
|||
using System.Diagnostics;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Linq
|
||||
{
|
||||
|
@ -212,6 +213,63 @@ namespace System.Linq
|
|||
|
||||
|
||||
private static ILookup<string, MethodInfo> s_seqMethods;
|
||||
|
||||
[PreserveDependency ("Aggregate`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Aggregate`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Aggregate`3", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("All`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Any`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Append`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Average", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Average`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Cast`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Concat`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Contains`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Count`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("DefaultIfEmpty`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Distinct`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("ElementAt`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("ElementAtOrDefault`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Except`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("First`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("FirstOrDefault`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("GroupBy`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("GroupBy`3", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("GroupBy`4", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("GroupJoin`4", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Intersect`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Join`4", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Last`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("LastOrDefault`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("LongCount`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Max`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Max`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Min`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Min`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("OfType`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("OrderBy`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("OrderByDescending`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Prepend`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Reverse`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Select`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("SelectMany`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("SelectMany`3", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("SequenceEqual`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Single`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("SingleOrDefault`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Skip`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("SkipLast`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("SkipWhile`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Sum", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Sum`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Take`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("TakeLast`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("TakeWhile`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("ThenBy`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("ThenByDescending`2", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Union`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Where`1", "System.Linq.Enumerable")]
|
||||
[PreserveDependency ("Zip`3", "System.Linq.Enumerable")]
|
||||
private static MethodInfo FindEnumerableMethod(string name, ReadOnlyCollection<Expression> args, params Type[] typeArgs)
|
||||
{
|
||||
if (s_seqMethods == null)
|
||||
|
|
|
@ -81,15 +81,23 @@ namespace System.Net.Http
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public Uri RequestUri
|
||||
{
|
||||
get { return _requestUri; }
|
||||
set
|
||||
{
|
||||
#if MONO
|
||||
if ((value != null) && (!IsAllowedAbsoluteUri(value)))
|
||||
{
|
||||
throw new ArgumentException(SR.net_http_client_http_baseaddress_required, nameof(value));
|
||||
}
|
||||
#else
|
||||
if ((value != null) && (value.IsAbsoluteUri) && (!HttpUtilities.IsHttpUri(value)))
|
||||
{
|
||||
throw new ArgumentException(SR.net_http_client_http_baseaddress_required, nameof(value));
|
||||
}
|
||||
#endif
|
||||
CheckDisposed();
|
||||
|
||||
// It's OK to set 'null'. HttpClient will add the 'BaseAddress'. If there is no 'BaseAddress'
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -76,7 +77,44 @@ namespace System.Net.Http
|
|||
|
||||
string challengeData = challenge.ChallengeData;
|
||||
|
||||
string spn = "HTTP/" + authUri.IdnHost;
|
||||
// Calculate SPN (Service Principal Name) using the host name of the request.
|
||||
// Use the request's 'Host' header if available. Otherwise, use the request uri.
|
||||
// Ignore the 'Host' header if this is proxy authentication since we need to use
|
||||
// the host name of the proxy itself for SPN calculation.
|
||||
string hostName;
|
||||
if (!isProxyAuth && request.HasHeaders && request.Headers.Host != null)
|
||||
{
|
||||
// Use the host name without any normalization.
|
||||
hostName = request.Headers.Host;
|
||||
if (NetEventSource.IsEnabled)
|
||||
{
|
||||
NetEventSource.Info(connection, $"Authentication: {challenge.AuthenticationType}, Host: {hostName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Need to use FQDN normalized host so that CNAME's are traversed.
|
||||
// Use DNS to do the forward lookup to an A (host) record.
|
||||
// But skip DNS lookup on IP literals. Otherwise, we would end up
|
||||
// doing an unintended reverse DNS lookup.
|
||||
UriHostNameType hnt = authUri.HostNameType;
|
||||
if (hnt == UriHostNameType.IPv6 || hnt == UriHostNameType.IPv4)
|
||||
{
|
||||
hostName = authUri.IdnHost;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPHostEntry result = await Dns.GetHostEntryAsync(authUri.IdnHost).ConfigureAwait(false);
|
||||
hostName = result.HostName;
|
||||
}
|
||||
}
|
||||
|
||||
string spn = "HTTP/" + hostName;
|
||||
if (NetEventSource.IsEnabled)
|
||||
{
|
||||
NetEventSource.Info(connection, $"Authentication: {challenge.AuthenticationType}, SPN: {spn}");
|
||||
}
|
||||
|
||||
ChannelBinding channelBinding = connection.TransportContext?.GetChannelBinding(ChannelBindingKind.Endpoint);
|
||||
NTAuthentication authContext = new NTAuthentication(isServer:false, challenge.SchemeName, challenge.Credential, spn, ContextFlagsPal.Connection, channelBinding);
|
||||
try
|
||||
|
@ -135,4 +173,3 @@ namespace System.Net.Http
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ using System.Threading.Tasks;
|
|||
namespace System.Net.Sockets
|
||||
{
|
||||
// Provides the underlying stream of data for network access.
|
||||
public class NetworkStream : Stream
|
||||
public partial class NetworkStream : Stream
|
||||
{
|
||||
// Used by the class to hold the underlying socket the stream uses.
|
||||
private readonly Socket _streamSocket;
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace System.Net.Sockets
|
|||
internal Task<Socket> AcceptAsync(Socket acceptSocket)
|
||||
{
|
||||
// Get any cached SocketAsyncEventArg we may have.
|
||||
TaskSocketAsyncEventArgs<Socket> saea = Interlocked.Exchange(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs).TaskAccept, s_rentedSocketSentinel);
|
||||
TaskSocketAsyncEventArgs<Socket> saea = Interlocked.Exchange(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs, () => { return new CachedEventArgs(); }).TaskAccept, s_rentedSocketSentinel);
|
||||
if (saea == s_rentedSocketSentinel)
|
||||
{
|
||||
// An instance was once created (or is currently being created elsewhere), but some other
|
||||
|
@ -194,7 +194,7 @@ namespace System.Net.Sockets
|
|||
return new ValueTask<int>(Task.FromCanceled<int>(cancellationToken));
|
||||
}
|
||||
|
||||
AwaitableSocketAsyncEventArgs saea = LazyInitializer.EnsureInitialized(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs).ValueTaskReceive);
|
||||
AwaitableSocketAsyncEventArgs saea = LazyInitializer.EnsureInitialized(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs, () => { return new CachedEventArgs(); } ).ValueTaskReceive, () => { return new AwaitableSocketAsyncEventArgs(); });
|
||||
if (saea.Reserve())
|
||||
{
|
||||
Debug.Assert(saea.BufferList == null);
|
||||
|
@ -343,7 +343,7 @@ namespace System.Net.Sockets
|
|||
return new ValueTask<int>(Task.FromCanceled<int>(cancellationToken));
|
||||
}
|
||||
|
||||
AwaitableSocketAsyncEventArgs saea = LazyInitializer.EnsureInitialized(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs).ValueTaskSend);
|
||||
AwaitableSocketAsyncEventArgs saea = LazyInitializer.EnsureInitialized(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs, () => { return new CachedEventArgs(); } ).ValueTaskSend, () => { return new AwaitableSocketAsyncEventArgs(); });
|
||||
if (saea.Reserve())
|
||||
{
|
||||
Debug.Assert(saea.BufferList == null);
|
||||
|
@ -367,7 +367,7 @@ namespace System.Net.Sockets
|
|||
return new ValueTask(Task.FromCanceled(cancellationToken));
|
||||
}
|
||||
|
||||
AwaitableSocketAsyncEventArgs saea = LazyInitializer.EnsureInitialized(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs).ValueTaskSend);
|
||||
AwaitableSocketAsyncEventArgs saea = LazyInitializer.EnsureInitialized(ref LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs, () => { return new CachedEventArgs(); } ).ValueTaskSend, () => { return new AwaitableSocketAsyncEventArgs(); });
|
||||
if (saea.Reserve())
|
||||
{
|
||||
Debug.Assert(saea.BufferList == null);
|
||||
|
@ -644,7 +644,7 @@ namespace System.Net.Sockets
|
|||
private Int32TaskSocketAsyncEventArgs RentSocketAsyncEventArgs(bool isReceive)
|
||||
{
|
||||
// Get any cached SocketAsyncEventArg we may have.
|
||||
CachedEventArgs cea = LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs);
|
||||
CachedEventArgs cea = LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs, () => { return new CachedEventArgs(); });
|
||||
Int32TaskSocketAsyncEventArgs saea = isReceive ?
|
||||
Interlocked.Exchange(ref cea.TaskReceive, s_rentedInt32Sentinel) :
|
||||
Interlocked.Exchange(ref cea.TaskSend, s_rentedInt32Sentinel);
|
||||
|
|
|
@ -215,6 +215,7 @@ namespace System.Net.Sockets.Tests
|
|||
|
||||
[Theory]
|
||||
[MemberData(nameof(ReadAsync_ContinuesOnCurrentContextIfDesired_MemberData))]
|
||||
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono, "Mono does not yet support `continueOnCapturedContext`.")]
|
||||
public async Task ReadAsync_ContinuesOnCurrentSynchronizationContextIfDesired(
|
||||
bool flowExecutionContext, bool? continueOnCapturedContext)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче