FreeRDP
Loading...
Searching...
No Matches
sspicli.c
1
20#include <winpr/config.h>
21
22#include <winpr/assert.h>
23#include <winpr/sspicli.h>
24
54#ifndef _WIN32
55
56#include <winpr/crt.h>
57
58#ifdef WINPR_HAVE_UNISTD_H
59#include <unistd.h>
60#endif
61
62#if defined(WINPR_HAVE_GETPWUID_R)
63#include <sys/types.h>
64#endif
65
66#include <pthread.h>
67
68#include <pwd.h>
69#include <grp.h>
70
71#include "../handle/handle.h"
72
73#include "../security/security.h"
74
75static BOOL LogonUserCloseHandle(HANDLE handle);
76
77static BOOL LogonUserIsHandled(HANDLE handle)
78{
79 return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_ACCESS_TOKEN, FALSE);
80}
81
82static int LogonUserGetFd(HANDLE handle)
83{
84 WINPR_ACCESS_TOKEN* pLogonUser = (WINPR_ACCESS_TOKEN*)handle;
85
86 if (!LogonUserIsHandled(handle))
87 return -1;
88
89 /* TODO: File fd not supported */
90 (void)pLogonUser;
91 return -1;
92}
93
94BOOL LogonUserCloseHandle(HANDLE handle)
95{
96 WINPR_ACCESS_TOKEN* token = (WINPR_ACCESS_TOKEN*)handle;
97
98 if (!handle || !LogonUserIsHandled(handle))
99 return FALSE;
100
101 free(token->Username);
102 free(token->Domain);
103 free(token);
104 return TRUE;
105}
106
107static HANDLE_OPS ops = { LogonUserIsHandled,
108 LogonUserCloseHandle,
109 LogonUserGetFd,
110 NULL, /* CleanupHandle */
111 NULL,
112 NULL,
113 NULL,
114 NULL,
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 NULL };
128
129BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, WINPR_ATTR_UNUSED LPCSTR lpszPassword,
130 WINPR_ATTR_UNUSED DWORD dwLogonType, WINPR_ATTR_UNUSED DWORD dwLogonProvider,
131 PHANDLE phToken)
132{
133 if (!lpszUsername)
134 return FALSE;
135
136 WINPR_ACCESS_TOKEN* token = (WINPR_ACCESS_TOKEN*)calloc(1, sizeof(WINPR_ACCESS_TOKEN));
137
138 if (!token)
139 return FALSE;
140
141 WINPR_HANDLE_SET_TYPE_AND_MODE(token, HANDLE_TYPE_ACCESS_TOKEN, WINPR_FD_READ);
142 token->common.ops = &ops;
143 token->Username = _strdup(lpszUsername);
144
145 if (!token->Username)
146 goto fail;
147
148 if (lpszDomain)
149 {
150 token->Domain = _strdup(lpszDomain);
151
152 if (!token->Domain)
153 goto fail;
154 }
155
156 long buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
157 if (buflen < 0)
158 buflen = 8196;
159
160 const size_t s = 1ULL + (size_t)buflen;
161 char* buf = (char*)calloc(s, sizeof(char));
162 if (!buf)
163 goto fail;
164
165 struct passwd pwd = { 0 };
166 struct passwd* pw = NULL;
167 const int rc =
168 getpwnam_r(lpszUsername, &pwd, buf, WINPR_ASSERTING_INT_CAST(size_t, buflen), &pw);
169 free(buf);
170 if ((rc == 0) && pw)
171 {
172 token->UserId = (DWORD)pw->pw_uid;
173 token->GroupId = (DWORD)pw->pw_gid;
174 }
175
176 *((ULONG_PTR*)phToken) = (ULONG_PTR)token;
177 return TRUE;
178
179fail:
180 free(token->Username);
181 free(token->Domain);
182 free(token);
183 return FALSE;
184}
185
186BOOL LogonUserW(WINPR_ATTR_UNUSED LPCWSTR lpszUsername, WINPR_ATTR_UNUSED LPCWSTR lpszDomain,
187 WINPR_ATTR_UNUSED LPCWSTR lpszPassword, WINPR_ATTR_UNUSED DWORD dwLogonType,
188 WINPR_ATTR_UNUSED DWORD dwLogonProvider, WINPR_ATTR_UNUSED PHANDLE phToken)
189{
190 WLog_ERR("TODO", "TODO: implement");
191 return TRUE;
192}
193
194BOOL LogonUserExA(WINPR_ATTR_UNUSED LPCSTR lpszUsername, WINPR_ATTR_UNUSED LPCSTR lpszDomain,
195 WINPR_ATTR_UNUSED LPCSTR lpszPassword, WINPR_ATTR_UNUSED DWORD dwLogonType,
196 WINPR_ATTR_UNUSED DWORD dwLogonProvider, WINPR_ATTR_UNUSED PHANDLE phToken,
197 WINPR_ATTR_UNUSED PSID* ppLogonSid, WINPR_ATTR_UNUSED PVOID* ppProfileBuffer,
198 WINPR_ATTR_UNUSED LPDWORD pdwProfileLength,
199 WINPR_ATTR_UNUSED PQUOTA_LIMITS pQuotaLimits)
200{
201 WLog_ERR("TODO", "TODO: implement");
202 return TRUE;
203}
204
205BOOL LogonUserExW(WINPR_ATTR_UNUSED LPCWSTR lpszUsername, WINPR_ATTR_UNUSED LPCWSTR lpszDomain,
206 WINPR_ATTR_UNUSED LPCWSTR lpszPassword, WINPR_ATTR_UNUSED DWORD dwLogonType,
207 WINPR_ATTR_UNUSED DWORD dwLogonProvider, WINPR_ATTR_UNUSED PHANDLE phToken,
208 WINPR_ATTR_UNUSED PSID* ppLogonSid, WINPR_ATTR_UNUSED PVOID* ppProfileBuffer,
209 WINPR_ATTR_UNUSED LPDWORD pdwProfileLength,
210 WINPR_ATTR_UNUSED PQUOTA_LIMITS pQuotaLimits)
211{
212 WLog_ERR("TODO", "TODO: implement");
213 return TRUE;
214}
215
216BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
217{
218 WINPR_ASSERT(lpNameBuffer);
219 WINPR_ASSERT(nSize);
220
221 switch (NameFormat)
222 {
223 case NameSamCompatible:
224#if defined(WINPR_HAVE_GETPWUID_R)
225 {
226 int rc = 0;
227 struct passwd pwd = { 0 };
228 struct passwd* result = NULL;
229 uid_t uid = getuid();
230
231 rc = getpwuid_r(uid, &pwd, lpNameBuffer, *nSize, &result);
232 if (rc != 0)
233 return FALSE;
234 if (result == NULL)
235 return FALSE;
236 }
237#elif defined(WINPR_HAVE_GETLOGIN_R)
238 if (getlogin_r(lpNameBuffer, *nSize) != 0)
239 return FALSE;
240#else
241 {
242 const char* name = getlogin();
243 if (!name)
244 return FALSE;
245 strncpy(lpNameBuffer, name, strnlen(name, *nSize));
246 }
247#endif
248 const size_t len = strnlen(lpNameBuffer, *nSize);
249 if (len > UINT32_MAX)
250 return FALSE;
251 *nSize = (ULONG)len;
252 return TRUE;
253
254 case NameFullyQualifiedDN:
255 case NameDisplay:
256 case NameUniqueId:
257 case NameCanonical:
258 case NameUserPrincipal:
259 case NameCanonicalEx:
260 case NameServicePrincipal:
261 case NameDnsDomain:
262 break;
263
264 default:
265 break;
266 }
267
268 return FALSE;
269}
270
271BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
272{
273 BOOL rc = FALSE;
274 char* name = NULL;
275
276 WINPR_ASSERT(nSize);
277 WINPR_ASSERT(lpNameBuffer);
278
279 name = calloc(1, *nSize + 1);
280 if (!name)
281 goto fail;
282
283 if (!GetUserNameExA(NameFormat, name, nSize))
284 goto fail;
285
286 const SSIZE_T res = ConvertUtf8ToWChar(name, lpNameBuffer, *nSize);
287 if ((res < 0) || (res >= UINT32_MAX))
288 goto fail;
289
290 *nSize = (UINT32)res + 1;
291 rc = TRUE;
292fail:
293 free(name);
294 return rc;
295}
296
297#endif