[SECUR32]
[reactos.git] / reactos / dll / win32 / secur32 / secext.c
1 /*
2 * Copyright (C) 2004 Juan Lang
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "precomp.h"
20
21 #include <winnls.h>
22 #include <lsass/lsass.h>
23
24 #define NDEBUG
25 #include <debug.h>
26
27 #define UNLEN 256
28
29 /***********************************************************************
30 * GetComputerObjectNameA (SECUR32.@) Wine 1.1.14
31 *
32 * Get the local computer's name using the format specified.
33 *
34 * PARAMS
35 * NameFormat [I] The format for the name.
36 * lpNameBuffer [O] Pointer to buffer to receive the name.
37 * nSize [I/O] Size in characters of buffer.
38 *
39 * RETURNS
40 * TRUE If the name was written to lpNameBuffer.
41 * FALSE If the name couldn't be written.
42 *
43 * NOTES
44 * If lpNameBuffer is NULL, then the size of the buffer needed to hold the
45 * name will be returned in *nSize.
46 *
47 * nSize returns the number of characters written when lpNameBuffer is not
48 * NULL or the size of the buffer needed to hold the name when the buffer
49 * is too short or lpNameBuffer is NULL.
50 *
51 * It the buffer is too short, ERROR_INSUFFICIENT_BUFFER error will be set.
52 */
53 BOOLEAN WINAPI GetComputerObjectNameA(
54 EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
55 {
56 BOOLEAN rc;
57 LPWSTR bufferW = NULL;
58 ULONG sizeW = *nSize;
59 DPRINT("(%d %p %p)\n", NameFormat, lpNameBuffer, nSize);
60 if (lpNameBuffer) {
61 bufferW = HeapAlloc(GetProcessHeap(), 0, sizeW * sizeof(WCHAR));
62 if (bufferW == NULL) {
63 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
64 return FALSE;
65 }
66 }
67 rc = GetComputerObjectNameW(NameFormat, bufferW, &sizeW);
68 if (rc && bufferW) {
69 ULONG len = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
70 WideCharToMultiByte(CP_ACP, 0, bufferW, -1, lpNameBuffer, *nSize, NULL, NULL);
71 *nSize = len;
72 }
73 else
74 *nSize = sizeW;
75 HeapFree(GetProcessHeap(), 0, bufferW);
76 return rc;
77 }
78
79 /***********************************************************************
80 * GetComputerObjectNameW (SECUR32.@) Wine 1.1.14
81 */
82 BOOLEAN WINAPI GetComputerObjectNameW(
83 EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
84 {
85 LSA_HANDLE policyHandle;
86 LSA_OBJECT_ATTRIBUTES objectAttributes;
87 PPOLICY_DNS_DOMAIN_INFO domainInfo;
88 NTSTATUS ntStatus;
89 BOOLEAN status;
90 DPRINT("(%d %p %p)\n", NameFormat, lpNameBuffer, nSize);
91
92 if (NameFormat == NameUnknown)
93 {
94 SetLastError(ERROR_INVALID_PARAMETER);
95 return FALSE;
96 }
97
98 ZeroMemory(&objectAttributes, sizeof(objectAttributes));
99 objectAttributes.Length = sizeof(objectAttributes);
100
101 ntStatus = LsaOpenPolicy(NULL, &objectAttributes,
102 POLICY_VIEW_LOCAL_INFORMATION,
103 &policyHandle);
104 if (ntStatus != STATUS_SUCCESS)
105 {
106 SetLastError(LsaNtStatusToWinError(ntStatus));
107 DPRINT1("LsaOpenPolicy failed with NT status %u\n", GetLastError());
108 return FALSE;
109 }
110
111 ntStatus = LsaQueryInformationPolicy(policyHandle,
112 PolicyDnsDomainInformation,
113 (PVOID *)&domainInfo);
114 if (ntStatus != STATUS_SUCCESS)
115 {
116 SetLastError(LsaNtStatusToWinError(ntStatus));
117 DPRINT1("LsaQueryInformationPolicy failed with NT status %u\n",
118 GetLastError());
119 LsaClose(policyHandle);
120 return FALSE;
121 }
122
123 if (domainInfo->Sid)
124 {
125 switch (NameFormat)
126 {
127 case NameSamCompatible:
128 {
129 WCHAR name[MAX_COMPUTERNAME_LENGTH + 1];
130 DWORD size = sizeof(name)/sizeof(name[0]);
131 if (GetComputerNameW(name, &size))
132 {
133 DWORD len = domainInfo->Name.Length + size + 3;
134 if (lpNameBuffer)
135 {
136 if (*nSize < len)
137 {
138 *nSize = len;
139 SetLastError(ERROR_INSUFFICIENT_BUFFER);
140 status = FALSE;
141 }
142 else
143 {
144 WCHAR bs[] = { '\\', 0 };
145 WCHAR ds[] = { '$', 0 };
146 lstrcpyW(lpNameBuffer, domainInfo->Name.Buffer);
147 lstrcatW(lpNameBuffer, bs);
148 lstrcatW(lpNameBuffer, name);
149 lstrcatW(lpNameBuffer, ds);
150 status = TRUE;
151 }
152 }
153 else /* just requesting length required */
154 {
155 *nSize = len;
156 status = TRUE;
157 }
158 }
159 else
160 {
161 SetLastError(ERROR_INTERNAL_ERROR);
162 status = FALSE;
163 }
164 }
165 break;
166 case NameFullyQualifiedDN:
167 case NameDisplay:
168 case NameUniqueId:
169 case NameCanonical:
170 case NameUserPrincipal:
171 case NameCanonicalEx:
172 case NameServicePrincipal:
173 case NameDnsDomain:
174 DPRINT1("NameFormat %d not implemented\n", NameFormat);
175 SetLastError(ERROR_CANT_ACCESS_DOMAIN_INFO);
176 status = FALSE;
177 break;
178 default:
179 SetLastError(ERROR_INVALID_PARAMETER);
180 status = FALSE;
181 }
182 }
183 else
184 {
185 SetLastError(ERROR_CANT_ACCESS_DOMAIN_INFO);
186 status = FALSE;
187 }
188
189 LsaFreeMemory(domainInfo);
190 LsaClose(policyHandle);
191
192 return status;
193 }
194
195
196 BOOLEAN WINAPI GetUserNameExA(
197 EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
198 {
199 BOOLEAN rc;
200 LPWSTR bufferW = NULL;
201 ULONG sizeW = *nSize;
202 DPRINT("(%d %p %p)\n", NameFormat, lpNameBuffer, nSize);
203 if (lpNameBuffer) {
204 bufferW = HeapAlloc(GetProcessHeap(), 0, sizeW * sizeof(WCHAR));
205 if (bufferW == NULL) {
206 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
207 return FALSE;
208 }
209 }
210 rc = GetUserNameExW(NameFormat, bufferW, &sizeW);
211 if (rc) {
212 ULONG len = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
213 if (len <= *nSize)
214 {
215 WideCharToMultiByte(CP_ACP, 0, bufferW, -1, lpNameBuffer, *nSize, NULL, NULL);
216 *nSize = len - 1;
217 }
218 else
219 {
220 *nSize = len;
221 rc = FALSE;
222 SetLastError(ERROR_MORE_DATA);
223 }
224 }
225 else
226 *nSize = sizeW;
227 HeapFree(GetProcessHeap(), 0, bufferW);
228 return rc;
229 }
230
231
232 BOOLEAN WINAPI GetUserNameExW(
233 EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
234 {
235 BOOLEAN status;
236 WCHAR samname[UNLEN + 1 + MAX_COMPUTERNAME_LENGTH + 1];
237 LPWSTR out;
238 DWORD len;
239 DPRINT("(%d %p %p)\n", NameFormat, lpNameBuffer, nSize);
240
241 switch (NameFormat)
242 {
243 case NameSamCompatible:
244 {
245 /* This assumes the current user is always a local account */
246 len = MAX_COMPUTERNAME_LENGTH + 1;
247 if (GetComputerNameW(samname, &len))
248 {
249 out = samname + lstrlenW(samname);
250 *out++ = '\\';
251 len = UNLEN + 1;
252 if (GetUserNameW(out, &len))
253 {
254 status = (lstrlenW(samname) < *nSize);
255 if (status)
256 {
257 lstrcpyW(lpNameBuffer, samname);
258 *nSize = lstrlenW(samname);
259 }
260 else
261 {
262 SetLastError(ERROR_MORE_DATA);
263 *nSize = lstrlenW(samname) + 1;
264 }
265 }
266 else
267 status = FALSE;
268 }
269 else
270 status = FALSE;
271 }
272 break;
273 case NameUnknown:
274 case NameFullyQualifiedDN:
275 case NameDisplay:
276 case NameUniqueId:
277 case NameCanonical:
278 case NameUserPrincipal:
279 case NameCanonicalEx:
280 case NameServicePrincipal:
281 case NameDnsDomain:
282 SetLastError(ERROR_NONE_MAPPED);
283 status = FALSE;
284 break;
285 default:
286 SetLastError(ERROR_INVALID_PARAMETER);
287 status = FALSE;
288 }
289
290 return status;
291 }