- added RECT support to the texture upload code
[wine] / dlls / netapi32 / access.c
1 /*
2  * Copyright 2002 Andriy Palamarchuk
3  *
4  * netapi32 access 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 "winerror.h"
23 #include "lmcons.h"
24 #include "lmaccess.h"
25 #include "lmapibuf.h"
26 #include "lmerr.h"
27 #include "netapi32_misc.h"
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
32
33 const WCHAR sAdminUserName[] = {'A','d','m','i','n','i','s','t','r','a','t',
34                                 'o','r',0};
35 const WCHAR sGuestUserName[] = {'G','u','e','s','t',0};
36
37 /************************************************************
38  *                NETAPI_ValidateServername
39  *
40  * Validates server name
41  */
42 NET_API_STATUS NETAPI_ValidateServername(LPCWSTR ServerName)
43 {
44     if (ServerName)
45     {
46         if (ServerName[0] == 0)
47             return ERROR_BAD_NETPATH;
48         else if (
49             ((ServerName[0] == '\\') &&
50              (ServerName[1] != '\\'))
51             ||
52             ((ServerName[0] == '\\') &&
53              (ServerName[1] == '\\') &&
54              (ServerName[2] == 0))
55             )
56             return ERROR_INVALID_NAME;
57     }
58     return NERR_Success;
59 }
60
61 /************************************************************
62  *                NETAPI_IsKnownUser
63  *
64  * Checks whether the user name indicates current user.
65  */
66 BOOL NETAPI_IsKnownUser(LPCWSTR UserName)
67 {
68     DWORD dwSize = UNLEN + 1;
69     BOOL Result;
70     LPWSTR buf;
71
72     if (!lstrcmpW(UserName, sAdminUserName) ||
73         !lstrcmpW(UserName, sGuestUserName))
74         return TRUE;
75     NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf);
76     Result = GetUserNameW(buf, &dwSize);
77
78     Result = Result && !lstrcmpW(UserName, buf);
79     NetApiBufferFree(buf);
80
81     return Result;
82 }
83
84 #define NETAPI_ForceKnownUser(UserName, FailureCode) \
85     if (!NETAPI_IsKnownUser(UserName)) \
86     { \
87         FIXME("Can't find information for user %s\n", \
88               debugstr_w(UserName)); \
89         return FailureCode; \
90     }
91
92 /************************************************************
93  *                NetUserGetInfo  (NETAPI32.@)
94  */
95 NET_API_STATUS WINAPI
96 NetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level,
97                LPBYTE* bufptr)
98 {
99     NET_API_STATUS status;
100     TRACE("(%s, %s, %ld, %p)\n", debugstr_w(servername), debugstr_w(username),
101           level, bufptr);
102     status = NETAPI_ValidateServername(servername);
103     if (status != NERR_Success)
104         return status;
105     NETAPI_ForceLocalComputer(servername, NERR_InvalidComputer);
106     NETAPI_ForceKnownUser(username, NERR_UserNotFound);
107
108     switch (level)
109     {
110     case 0:
111     {
112         PUSER_INFO_0 ui;
113         int name_sz;
114
115         name_sz = lstrlenW(username) + 1;
116
117         /* set up buffer */
118         NetApiBufferAllocate(sizeof(USER_INFO_0) + name_sz * sizeof(WCHAR),
119                              (LPVOID *) bufptr);
120
121         ui = (PUSER_INFO_0) *bufptr;
122         ui->usri0_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_0));
123
124         /* get data */
125         lstrcpyW(ui->usri0_name, username);
126         break;
127     }
128
129     case 10:
130     {
131         PUSER_INFO_10 ui;
132         PUSER_INFO_0 ui0;
133         NET_API_STATUS status;
134         /* sizes of the field buffers in WCHARS */
135         int name_sz, comment_sz, usr_comment_sz, full_name_sz;
136
137         comment_sz = 1;
138         usr_comment_sz = 1;
139         full_name_sz = 1;
140
141         /* get data */
142         status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0);
143         if (status != NERR_Success)
144         {
145             NetApiBufferFree(ui0);
146             return status;
147         }
148         name_sz = lstrlenW(ui0->usri0_name) + 1;
149
150         /* set up buffer */
151         NetApiBufferAllocate(sizeof(USER_INFO_10) +
152                              (name_sz + comment_sz + usr_comment_sz +
153                               full_name_sz) * sizeof(WCHAR),
154                              (LPVOID *) bufptr);
155         ui = (PUSER_INFO_10) *bufptr;
156         ui->usri10_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_10));
157         ui->usri10_comment = (LPWSTR) (
158             ((PBYTE) ui->usri10_name) + name_sz * sizeof(WCHAR));
159         ui->usri10_usr_comment = (LPWSTR) (
160             ((PBYTE) ui->usri10_comment) + comment_sz * sizeof(WCHAR));
161         ui->usri10_full_name = (LPWSTR) (
162             ((PBYTE) ui->usri10_usr_comment) + usr_comment_sz * sizeof(WCHAR));
163
164         /* set data */
165         lstrcpyW(ui->usri10_name, ui0->usri0_name);
166         NetApiBufferFree(ui0);
167         ui->usri10_comment[0] = 0;
168         ui->usri10_usr_comment[0] = 0;
169         ui->usri10_full_name[0] = 0;
170         break;
171     }
172
173     case 1:
174       {
175         static const WCHAR homedirW[] = {'H','O','M','E',0};
176         PUSER_INFO_1 ui;
177         PUSER_INFO_0 ui0;
178         NET_API_STATUS status;
179         /* sizes of the field buffers in WCHARS */
180         int name_sz, password_sz, home_dir_sz, comment_sz, script_path_sz;
181
182         password_sz = 1; /* not filled out for security reasons for NetUserGetInfo*/
183         comment_sz = 1;
184         script_path_sz = 1;
185
186        /* get data */
187         status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0);
188         if (status != NERR_Success)
189         {
190             NetApiBufferFree(ui0);
191             return status;
192         }
193         name_sz = lstrlenW(ui0->usri0_name) + 1;
194         home_dir_sz = GetEnvironmentVariableW(homedirW, NULL,0);
195         /* set up buffer */
196         NetApiBufferAllocate(sizeof(USER_INFO_1) +
197                              (name_sz + password_sz + home_dir_sz +
198                               comment_sz + script_path_sz) * sizeof(WCHAR),
199                              (LPVOID *) bufptr);
200
201         ui = (PUSER_INFO_1) *bufptr;
202         ui->usri1_name = (LPWSTR) (ui + 1);
203         ui->usri1_password = ui->usri1_name + name_sz;
204         ui->usri1_home_dir = ui->usri1_password + password_sz;
205         ui->usri1_comment = ui->usri1_home_dir + home_dir_sz;
206         ui->usri1_script_path = ui->usri1_comment + comment_sz;
207         /* set data */
208         lstrcpyW(ui->usri1_name, ui0->usri0_name);
209         NetApiBufferFree(ui0);
210         ui->usri1_password[0] = 0;
211         ui->usri1_password_age = 0;
212         ui->usri1_priv = 0;
213         GetEnvironmentVariableW(homedirW, ui->usri1_home_dir,home_dir_sz);
214         ui->usri1_comment[0] = 0;
215         ui->usri1_flags = 0;
216         ui->usri1_script_path[0] = 0;
217         break;
218       }
219     case 2:
220     case 3:
221     case 4:
222     case 11:
223     case 20:
224     case 23:
225     case 1003:
226     case 1005:
227     case 1006:
228     case 1007:
229     case 1008:
230     case 1009:
231     case 1010:
232     case 1011:
233     case 1012:
234     case 1013:
235     case 1014:
236     case 1017:
237     case 1018:
238     case 1020:
239     case 1023:
240     case 1024:
241     case 1025:
242     case 1051:
243     case 1052:
244     case 1053:
245     {
246         FIXME("Level %ld is not implemented\n", level);
247         break;
248     }
249     default:
250         ERR("Invalid level %ld is specified\n", level);
251         return ERROR_INVALID_LEVEL;
252     }
253     return NERR_Success;
254 }
255
256 /************************************************************
257  *                ACCESS_QueryAdminDisplayInformation
258  *
259  *  Creates a buffer with information for the Admin User
260  */
261 void ACCESS_QueryAdminDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD pdwSize)
262 {
263     const WCHAR sAdminUserName[] = {
264         'A','d','m','i','n','i','s','t','r','a','t','o','r',0};
265
266     /* sizes of the field buffers in WCHARS */
267     int name_sz, comment_sz, full_name_sz;
268     PNET_DISPLAY_USER usr;
269
270     /* set up buffer */
271     name_sz = lstrlenW(sAdminUserName);
272     comment_sz = 1;
273     full_name_sz = 1;
274     
275     *pdwSize = sizeof(NET_DISPLAY_USER);
276     *pdwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
277     NetApiBufferAllocate(*pdwSize, (LPVOID *) buf);
278
279     usr = *buf;
280     usr->usri1_name = (LPWSTR) ((PBYTE) usr + sizeof(NET_DISPLAY_USER));
281     usr->usri1_comment = (LPWSTR) (
282         ((PBYTE) usr->usri1_name) + name_sz * sizeof(WCHAR));
283     usr->usri1_full_name = (LPWSTR) (
284         ((PBYTE) usr->usri1_comment) + comment_sz * sizeof(WCHAR));
285
286     /* set data */
287     lstrcpyW(usr->usri1_name, sAdminUserName);
288     usr->usri1_comment[0] = 0;
289     usr->usri1_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD;
290     usr->usri1_full_name[0] = 0;
291     usr->usri1_user_id = 500;
292     usr->usri1_next_index = 0;
293 }
294
295 /************************************************************
296  *                ACCESS_QueryGuestDisplayInformation
297  *
298  *  Creates a buffer with information for the Guest User
299  */
300 void ACCESS_QueryGuestDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD pdwSize)
301 {
302     const WCHAR sGuestUserName[] = {
303         'G','u','e','s','t',0 };
304
305     /* sizes of the field buffers in WCHARS */
306     int name_sz, comment_sz, full_name_sz;
307     PNET_DISPLAY_USER usr;
308
309     /* set up buffer */
310     name_sz = lstrlenW(sGuestUserName);
311     comment_sz = 1;
312     full_name_sz = 1;
313     
314     *pdwSize = sizeof(NET_DISPLAY_USER);
315     *pdwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
316     NetApiBufferAllocate(*pdwSize, (LPVOID *) buf);
317
318     usr = *buf;
319     usr->usri1_name = (LPWSTR) ((PBYTE) usr + sizeof(NET_DISPLAY_USER));
320     usr->usri1_comment = (LPWSTR) (
321         ((PBYTE) usr->usri1_name) + name_sz * sizeof(WCHAR));
322     usr->usri1_full_name = (LPWSTR) (
323         ((PBYTE) usr->usri1_comment) + comment_sz * sizeof(WCHAR));
324
325     /* set data */
326     lstrcpyW(usr->usri1_name, sGuestUserName);
327     usr->usri1_comment[0] = 0;
328     usr->usri1_flags = UF_ACCOUNTDISABLE | UF_SCRIPT | UF_NORMAL_ACCOUNT |
329         UF_DONT_EXPIRE_PASSWD;
330     usr->usri1_full_name[0] = 0;
331     usr->usri1_user_id = 500;
332     usr->usri1_next_index = 0;
333 }
334
335 /************************************************************
336  *                NetQueryDisplayInformation  (NETAPI32.@)
337  * Copies NET_DISPLAY_USER record.
338  */
339 void ACCESS_CopyDisplayUser(PNET_DISPLAY_USER dest, LPWSTR *dest_buf,
340                             PNET_DISPLAY_USER src)
341 {
342     LPWSTR str = *dest_buf;
343
344     src->usri1_name = str;
345     lstrcpyW(src->usri1_name, dest->usri1_name);
346     str = (LPWSTR) (
347         ((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
348
349     src->usri1_comment = str;
350     lstrcpyW(src->usri1_comment, dest->usri1_comment);
351     str = (LPWSTR) (
352         ((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
353
354     src->usri1_flags = dest->usri1_flags;
355
356     src->usri1_full_name = str;
357     lstrcpyW(src->usri1_full_name, dest->usri1_full_name);
358     str = (LPWSTR) (
359         ((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
360
361     src->usri1_user_id = dest->usri1_user_id;
362     src->usri1_next_index = dest->usri1_next_index;
363     *dest_buf = str;
364 }
365
366 /************************************************************
367  *                NetQueryDisplayInformation  (NETAPI32.@)
368  *
369  * The buffer structure:
370  * - array of fixed size record of the level type
371  * - strings, referenced by the record of the level type
372  */
373 NET_API_STATUS WINAPI
374 NetQueryDisplayInformation(
375     LPWSTR ServerName, DWORD Level, DWORD Index, DWORD EntriesRequested,
376     DWORD PreferredMaximumLength, LPDWORD ReturnedEntryCount,
377     PVOID *SortedBuffer)
378 {
379     TRACE("(%s, %ld, %ld, %ld, %ld, %p, %p)\n", debugstr_w(ServerName),
380           Level, Index, EntriesRequested, PreferredMaximumLength,
381           ReturnedEntryCount, SortedBuffer);
382     NETAPI_ForceLocalComputer(ServerName, ERROR_ACCESS_DENIED);
383     switch (Level)
384     {
385     case 1:
386     {
387         /* current record */
388         PNET_DISPLAY_USER inf;
389         /* current available strings buffer */
390         LPWSTR str;
391         PNET_DISPLAY_USER admin, guest;
392         DWORD admin_size, guest_size;
393         LPWSTR name = NULL;
394         DWORD dwSize;
395
396         /* sizes of the field buffers in WCHARS */
397         int name_sz, comment_sz, full_name_sz;
398
399         /* number of the records, returned in SortedBuffer
400            3 - for current user, Administrator and Guest users
401          */
402         int records = 3;
403
404         FIXME("Level %ld partially implemented\n", Level);
405         *ReturnedEntryCount = records;
406         comment_sz = 1;
407         full_name_sz = 1;
408
409         /* get data */
410         dwSize = UNLEN + 1;
411         NetApiBufferAllocate(dwSize, (LPVOID *) &name);
412         if (!GetUserNameW(name, &dwSize))
413         {
414             NetApiBufferFree(name);
415             return ERROR_ACCESS_DENIED;
416         }
417         name_sz = dwSize;
418         ACCESS_QueryAdminDisplayInformation(&admin, &admin_size);
419         ACCESS_QueryGuestDisplayInformation(&guest, &guest_size);
420
421         /* set up buffer */
422         dwSize = sizeof(NET_DISPLAY_USER) * records;
423         dwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
424
425         NetApiBufferAllocate(dwSize +
426                              admin_size - sizeof(NET_DISPLAY_USER) +
427                              guest_size - sizeof(NET_DISPLAY_USER),
428                              (LPVOID *) SortedBuffer);
429         inf = (PNET_DISPLAY_USER) *SortedBuffer;
430         str = (LPWSTR) ((PBYTE) inf + sizeof(NET_DISPLAY_USER) * records);
431         inf->usri1_name = str;
432         str = (LPWSTR) (
433             ((PBYTE) str) + name_sz * sizeof(WCHAR));
434         inf->usri1_comment = str;
435         str = (LPWSTR) (
436             ((PBYTE) str) + comment_sz * sizeof(WCHAR));
437         inf->usri1_full_name = str;
438         str = (LPWSTR) (
439             ((PBYTE) str) + full_name_sz * sizeof(WCHAR));
440
441         /* set data */
442         lstrcpyW(inf->usri1_name, name);
443         NetApiBufferFree(name);
444         inf->usri1_comment[0] = 0;
445         inf->usri1_flags =
446             UF_SCRIPT | UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD;
447         inf->usri1_full_name[0] = 0;
448         inf->usri1_user_id = 0;
449         inf->usri1_next_index = 0;
450
451         inf++;
452         ACCESS_CopyDisplayUser(admin, &str, inf);
453         NetApiBufferFree(admin);
454
455         inf++;
456         ACCESS_CopyDisplayUser(guest, &str, inf);
457         NetApiBufferFree(guest);
458         break;
459     }
460
461     case 2:
462     case 3:
463     {
464         FIXME("Level %ld is not implemented\n", Level);
465         break;
466     }
467
468     default:
469         ERR("Invalid level %ld is specified\n", Level);
470         return ERROR_INVALID_LEVEL;
471     }
472     return NERR_Success;
473 }
474
475 /************************************************************
476  *                NetGetDCName  (NETAPI32.@)
477  *
478  *  Return the name of the primary domain controller (PDC)
479  */
480
481 NET_API_STATUS WINAPI
482 NetGetDCName(LPWSTR servername, LPWSTR domainname, LPBYTE bufptr)
483 {
484   FIXME("stub!\n");
485   return NERR_DCNotFound; /* say we can't find a domain controller */  
486 }
487
488