summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/sspicli/sspicli.c
diff options
context:
space:
mode:
Diffstat (limited to 'winpr/libwinpr/sspicli/sspicli.c')
-rw-r--r--winpr/libwinpr/sspicli/sspicli.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/winpr/libwinpr/sspicli/sspicli.c b/winpr/libwinpr/sspicli/sspicli.c
new file mode 100644
index 0000000..f3e922c
--- /dev/null
+++ b/winpr/libwinpr/sspicli/sspicli.c
@@ -0,0 +1,275 @@
+/**
+ * WinPR: Windows Portable Runtime
+ * Security Support Provider Interface
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <winpr/config.h>
+
+#include <winpr/assert.h>
+#include <winpr/sspicli.h>
+
+/**
+ * sspicli.dll:
+ *
+ * EnumerateSecurityPackagesA
+ * EnumerateSecurityPackagesW
+ * GetUserNameExW
+ * ImportSecurityContextA
+ * LogonUser
+ * LogonUserEx
+ * LogonUserExExW
+ * SspiCompareAuthIdentities
+ * SspiCopyAuthIdentity
+ * SspiDecryptAuthIdentity
+ * SspiEncodeAuthIdentityAsStrings
+ * SspiEncodeStringsAsAuthIdentity
+ * SspiEncryptAuthIdentity
+ * SspiExcludePackage
+ * SspiFreeAuthIdentity
+ * SspiGetTargetHostName
+ * SspiIsAuthIdentityEncrypted
+ * SspiLocalFree
+ * SspiMarshalAuthIdentity
+ * SspiPrepareForCredRead
+ * SspiPrepareForCredWrite
+ * SspiUnmarshalAuthIdentity
+ * SspiValidateAuthIdentity
+ * SspiZeroAuthIdentity
+ */
+
+#ifndef _WIN32
+
+#include <winpr/crt.h>
+
+#ifdef WINPR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if defined(WINPR_HAVE_GETPWUID_R)
+#include <sys/types.h>
+#endif
+
+#include <pthread.h>
+
+#include <pwd.h>
+#include <grp.h>
+
+#include "../handle/handle.h"
+
+#include "../security/security.h"
+
+static BOOL LogonUserCloseHandle(HANDLE handle);
+
+static BOOL LogonUserIsHandled(HANDLE handle)
+{
+ return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_ACCESS_TOKEN, FALSE);
+}
+
+static int LogonUserGetFd(HANDLE handle)
+{
+ WINPR_ACCESS_TOKEN* pLogonUser = (WINPR_ACCESS_TOKEN*)handle;
+
+ if (!LogonUserIsHandled(handle))
+ return -1;
+
+ /* TODO: File fd not supported */
+ (void)pLogonUser;
+ return -1;
+}
+
+BOOL LogonUserCloseHandle(HANDLE handle)
+{
+ WINPR_ACCESS_TOKEN* token = (WINPR_ACCESS_TOKEN*)handle;
+
+ if (!handle || !LogonUserIsHandled(handle))
+ return FALSE;
+
+ free(token->Username);
+ free(token->Domain);
+ free(token);
+ return TRUE;
+}
+
+static HANDLE_OPS ops = { LogonUserIsHandled,
+ LogonUserCloseHandle,
+ LogonUserGetFd,
+ NULL, /* CleanupHandle */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL };
+
+BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, DWORD dwLogonType,
+ DWORD dwLogonProvider, PHANDLE phToken)
+{
+ struct passwd* pw = NULL;
+ WINPR_ACCESS_TOKEN* token = NULL;
+
+ if (!lpszUsername)
+ return FALSE;
+
+ token = (WINPR_ACCESS_TOKEN*)calloc(1, sizeof(WINPR_ACCESS_TOKEN));
+
+ if (!token)
+ return FALSE;
+
+ WINPR_HANDLE_SET_TYPE_AND_MODE(token, HANDLE_TYPE_ACCESS_TOKEN, WINPR_FD_READ);
+ token->common.ops = &ops;
+ token->Username = _strdup(lpszUsername);
+
+ if (!token->Username)
+ {
+ free(token);
+ return FALSE;
+ }
+
+ if (lpszDomain)
+ {
+ token->Domain = _strdup(lpszDomain);
+
+ if (!token->Domain)
+ {
+ free(token->Username);
+ free(token);
+ return FALSE;
+ }
+ }
+
+ pw = getpwnam(lpszUsername);
+
+ if (pw)
+ {
+ token->UserId = (DWORD)pw->pw_uid;
+ token->GroupId = (DWORD)pw->pw_gid;
+ }
+
+ *((ULONG_PTR*)phToken) = (ULONG_PTR)token;
+ return TRUE;
+}
+
+BOOL LogonUserW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, DWORD dwLogonType,
+ DWORD dwLogonProvider, PHANDLE phToken)
+{
+ return TRUE;
+}
+
+BOOL LogonUserExA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, DWORD dwLogonType,
+ DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, PVOID* ppProfileBuffer,
+ LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits)
+{
+ return TRUE;
+}
+
+BOOL LogonUserExW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, DWORD dwLogonType,
+ DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, PVOID* ppProfileBuffer,
+ LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits)
+{
+ return TRUE;
+}
+
+BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
+{
+ WINPR_ASSERT(lpNameBuffer);
+ WINPR_ASSERT(nSize);
+
+ switch (NameFormat)
+ {
+ case NameSamCompatible:
+#if defined(WINPR_HAVE_GETPWUID_R)
+ {
+ int rc = 0;
+ struct passwd pwd = { 0 };
+ struct passwd* result = NULL;
+ uid_t uid = getuid();
+
+ rc = getpwuid_r(uid, &pwd, lpNameBuffer, *nSize, &result);
+ if (rc != 0)
+ return FALSE;
+ if (result == NULL)
+ return FALSE;
+ }
+#elif defined(WINPR_HAVE_GETLOGIN_R)
+ if (getlogin_r(lpNameBuffer, *nSize) != 0)
+ return FALSE;
+#else
+ {
+ const char* name = getlogin();
+ if (!name)
+ return FALSE;
+ strncpy(lpNameBuffer, name, strnlen(name, *nSize));
+ }
+#endif
+ *nSize = strnlen(lpNameBuffer, *nSize);
+ return TRUE;
+
+ case NameFullyQualifiedDN:
+ case NameDisplay:
+ case NameUniqueId:
+ case NameCanonical:
+ case NameUserPrincipal:
+ case NameCanonicalEx:
+ case NameServicePrincipal:
+ case NameDnsDomain:
+ break;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
+{
+ BOOL rc = FALSE;
+ char* name = NULL;
+
+ WINPR_ASSERT(nSize);
+ WINPR_ASSERT(lpNameBuffer);
+
+ name = calloc(1, *nSize + 1);
+ if (!name)
+ goto fail;
+
+ if (!GetUserNameExA(NameFormat, name, nSize))
+ goto fail;
+
+ const SSIZE_T res = ConvertUtf8ToWChar(name, lpNameBuffer, *nSize);
+ if (res < 0)
+ goto fail;
+
+ *nSize = res + 1;
+ rc = TRUE;
+fail:
+ free(name);
+ return rc;
+}
+
+#endif