NetUserGetInfo: implemented Level 1.
[wine] / dlls / netapi32 / wksta.c
1 /*
2  * Copyright 2002 Andriy Palamarchuk
3  *
4  * netapi32 user functions
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "winbase.h"
22 #include "nb30.h"
23 #include "lmcons.h"
24 #include "lmapibuf.h"
25 #include "lmerr.h"
26 #include "lmwksta.h"
27 #include "winerror.h"
28 #include "winternl.h"
29 #include "ntsecapi.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
33
34 /************************************************************
35  *                NETAPI_IsLocalComputer
36  *
37  * Checks whether the server name indicates local machine.
38  */
39 BOOL NETAPI_IsLocalComputer(LPCWSTR ServerName)
40 {
41     if (!ServerName)
42     {
43         return TRUE;
44     }
45     else
46     {
47         DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
48         BOOL Result;
49         LPWSTR buf;
50
51         NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf);
52         Result = GetComputerNameW(buf,  &dwSize);
53         if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
54             ServerName += 2;
55         Result = Result && !lstrcmpW(ServerName, buf);
56         NetApiBufferFree(buf);
57
58         return Result;
59     }
60 }
61
62 /************************************************************
63  *                NetWkstaUserGetInfo  (NETAPI32.@)
64  */
65 NET_API_STATUS WINAPI NetWkstaUserGetInfo(LPWSTR reserved, DWORD level,
66                                           PBYTE* bufptr)
67 {
68     TRACE("(%s, %ld, %p)\n", debugstr_w(reserved), level, bufptr);
69     switch (level)
70     {
71     case 0:
72     {
73         PWKSTA_USER_INFO_0 ui;
74         DWORD dwSize = UNLEN + 1;
75
76         /* set up buffer */
77         NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_0) + dwSize * sizeof(WCHAR),
78                              (LPVOID *) bufptr);
79
80         ui = (PWKSTA_USER_INFO_0) *bufptr;
81         ui->wkui0_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0));
82
83         /* get data */
84         if (!GetUserNameW(ui->wkui0_username, &dwSize))
85         {
86             NetApiBufferFree(ui);
87             return ERROR_NOT_ENOUGH_MEMORY;
88         }
89         else
90             NetApiBufferReallocate(
91                 *bufptr, sizeof(WKSTA_USER_INFO_0) +
92                 (lstrlenW(ui->wkui0_username) + 1) * sizeof(WCHAR),
93                 (LPVOID *) bufptr);
94         break;
95     }
96
97     case 1:
98     {
99         PWKSTA_USER_INFO_1 ui;
100         PWKSTA_USER_INFO_0 ui0;
101         DWORD dwSize;
102         LSA_OBJECT_ATTRIBUTES ObjectAttributes;
103         LSA_HANDLE PolicyHandle;
104         PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo;
105         NTSTATUS NtStatus;
106
107         /* sizes of the field buffers in WCHARS */
108         int username_sz, logon_domain_sz, oth_domains_sz, logon_server_sz;
109
110         FIXME("Level 1 processing is partially implemented\n");
111         oth_domains_sz = 1;
112         logon_server_sz = 1;
113
114         /* get some information first to estimate size of the buffer */
115         ui0 = NULL;
116         NetWkstaUserGetInfo(NULL, 0, (PBYTE *) &ui0);
117         username_sz = lstrlenW(ui0->wkui0_username) + 1;
118
119         ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
120         NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes,
121                                  POLICY_VIEW_LOCAL_INFORMATION,
122                                  &PolicyHandle);
123         if (NtStatus != STATUS_SUCCESS)
124         {
125             ERR("LsaOpenPolicyFailed with NT status %lx\n",
126                 LsaNtStatusToWinError(NtStatus));
127             NetApiBufferFree(ui0);
128             return ERROR_NOT_ENOUGH_MEMORY;
129         }
130         LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation,
131                                   (PVOID*) &DomainInfo);
132         logon_domain_sz = lstrlenW(DomainInfo->DomainName.Buffer) + 1;
133         LsaClose(PolicyHandle);
134
135         /* set up buffer */
136         NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1) +
137                              (username_sz + logon_domain_sz +
138                               oth_domains_sz + logon_server_sz) * sizeof(WCHAR),
139                              (LPVOID *) bufptr);
140         ui = (WKSTA_USER_INFO_1 *) *bufptr;
141         ui->wkui1_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_1));
142         ui->wkui1_logon_domain = (LPWSTR) (
143             ((PBYTE) ui->wkui1_username) + username_sz * sizeof(WCHAR));
144         ui->wkui1_oth_domains = (LPWSTR) (
145             ((PBYTE) ui->wkui1_logon_domain) +
146             logon_domain_sz * sizeof(WCHAR));
147         ui->wkui1_logon_server = (LPWSTR) (
148             ((PBYTE) ui->wkui1_oth_domains) +
149             oth_domains_sz * sizeof(WCHAR));
150
151         /* get data */
152         dwSize = username_sz;
153         lstrcpyW(ui->wkui1_username, ui0->wkui0_username);
154         NetApiBufferFree(ui0);
155
156         lstrcpynW(ui->wkui1_logon_domain, DomainInfo->DomainName.Buffer,
157                 logon_domain_sz);
158         LsaFreeMemory(DomainInfo);
159
160         /* FIXME. Not implemented. Populated with empty strings */
161         ui->wkui1_oth_domains[0] = 0;
162         ui->wkui1_logon_server[0] = 0;
163         break;
164     }
165     case 1101:
166     {
167         PWKSTA_USER_INFO_1101 ui;
168         DWORD dwSize = 1;
169
170         FIXME("Stub. Level 1101 processing is not implemented\n");
171         /* FIXME see also wkui1_oth_domains for level 1 */
172
173         /* set up buffer */
174         NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1101) + dwSize * sizeof(WCHAR),
175                              (LPVOID *) bufptr);
176
177         ui = (PWKSTA_USER_INFO_1101) *bufptr;
178         ui->wkui1101_oth_domains = (LPWSTR)(ui + 1);
179
180         /* get data */
181         ui->wkui1101_oth_domains[0] = 0;
182         break;
183     }
184     default:
185         ERR("Invalid level %ld is specified\n", level);
186         return ERROR_INVALID_LEVEL;
187     }
188     return NERR_Success;
189 }
190
191 /************************************************************
192  *                NetpGetComputerName  (NETAPI32.@)
193  */
194 NET_API_STATUS WINAPI NetpGetComputerName(LPWSTR *Buffer)
195 {
196     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
197
198     TRACE("(%p)\n", Buffer);
199     NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) Buffer);
200     if (GetComputerNameW(*Buffer,  &dwSize))
201     {
202         NetApiBufferReallocate(
203             *Buffer, dwSize * sizeof(WCHAR),
204             (LPVOID *) Buffer);
205         return NERR_Success;
206     }
207     else
208     {
209         NetApiBufferFree(*Buffer);
210         return ERROR_NOT_ENOUGH_MEMORY;
211     }
212 }