xref: /reactos/base/services/wkssvc/rpcserver.c (revision 55b93aec)
1 /*
2  *  ReactOS Services
3  *  Copyright (C) 2015 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT:        See COPYING in the top level directory
21  * PROJECT:          ReactOS Services
22  * FILE:             base/services/wkssvc/rpcserver.c
23  * PURPOSE:          Workstation service
24  * PROGRAMMER:       Eric Kohl
25  */
26 
27 /* INCLUDES *****************************************************************/
28 
29 #include "precomp.h"
30 
31 #include "lmerr.h"
32 
33 WINE_DEFAULT_DEBUG_CHANNEL(wkssvc);
34 
35 /* FUNCTIONS *****************************************************************/
36 
37 DWORD
38 WINAPI
39 RpcThreadRoutine(
40     LPVOID lpParameter)
41 {
42     RPC_STATUS Status;
43 
44     Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\wkssvc", NULL);
45     if (Status != RPC_S_OK)
46     {
47         ERR("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
48         return 0;
49     }
50 
51     Status = RpcServerRegisterIf(wkssvc_v1_0_s_ifspec, NULL, NULL);
52     if (Status != RPC_S_OK)
53     {
54         ERR("RpcServerRegisterIf() failed (Status %lx)\n", Status);
55         return 0;
56     }
57 
58     Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
59     if (Status != RPC_S_OK)
60     {
61         ERR("RpcServerListen() failed (Status %lx)\n", Status);
62     }
63 
64     return 0;
65 }
66 
67 
68 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
69 {
70     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
71 }
72 
73 
74 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
75 {
76     HeapFree(GetProcessHeap(), 0, ptr);
77 }
78 
79 
80 /* Function 0 */
81 unsigned long
82 __stdcall
83 NetrWkstaGetInfo(
84     WKSSVC_IDENTIFY_HANDLE ServerName,
85     unsigned long Level,
86     LPWKSTA_INFO *WkstaInfo)
87 {
88     WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
89     DWORD dwComputerNameLength;
90     LPCWSTR pszLanRoot = L"";
91     PWKSTA_INFO pWkstaInfo = NULL;
92     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
93     LSA_HANDLE PolicyHandle;
94     PPOLICY_PRIMARY_DOMAIN_INFO DomainInfo = NULL;
95     NTSTATUS NtStatus;
96     DWORD dwResult = NERR_Success;
97 
98     TRACE("NetrWkstaGetInfo level %lu\n", Level);
99 
100     dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
101     GetComputerNameW(szComputerName, &dwComputerNameLength);
102     dwComputerNameLength++; /* include NULL terminator */
103 
104     ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
105     NtStatus = LsaOpenPolicy(NULL,
106                              &ObjectAttributes,
107                              POLICY_VIEW_LOCAL_INFORMATION,
108                              &PolicyHandle);
109     if (NtStatus != STATUS_SUCCESS)
110     {
111         WARN("LsaOpenPolicy() failed (Status 0x%08lx)\n", NtStatus);
112         return LsaNtStatusToWinError(NtStatus);
113     }
114 
115     NtStatus = LsaQueryInformationPolicy(PolicyHandle,
116                                          PolicyPrimaryDomainInformation,
117                                          (PVOID*)&DomainInfo);
118 
119     LsaClose(PolicyHandle);
120 
121     if (NtStatus != STATUS_SUCCESS)
122     {
123         WARN("LsaQueryInformationPolicy() failed (Status 0x%08lx)\n", NtStatus);
124         return LsaNtStatusToWinError(NtStatus);
125     }
126 
127     switch (Level)
128     {
129         case 100:
130             pWkstaInfo = midl_user_allocate(sizeof(WKSTA_INFO_100));
131             if (pWkstaInfo == NULL)
132             {
133                 dwResult = ERROR_NOT_ENOUGH_MEMORY;
134                 break;
135             }
136 
137             pWkstaInfo->WkstaInfo100.wki100_platform_id = PLATFORM_ID_NT;
138 
139             pWkstaInfo->WkstaInfo100.wki100_computername = midl_user_allocate(dwComputerNameLength * sizeof(WCHAR));
140             if (pWkstaInfo->WkstaInfo100.wki100_computername != NULL)
141                 wcscpy(pWkstaInfo->WkstaInfo100.wki100_computername, szComputerName);
142 
143             pWkstaInfo->WkstaInfo100.wki100_langroup = midl_user_allocate((wcslen(DomainInfo->Name.Buffer) + 1) * sizeof(WCHAR));
144             if (pWkstaInfo->WkstaInfo100.wki100_langroup != NULL)
145                 wcscpy(pWkstaInfo->WkstaInfo100.wki100_langroup, DomainInfo->Name.Buffer);
146 
147             pWkstaInfo->WkstaInfo100.wki100_ver_major = VersionInfo.dwMajorVersion;
148             pWkstaInfo->WkstaInfo100.wki100_ver_minor = VersionInfo.dwMinorVersion;
149 
150             *WkstaInfo = pWkstaInfo;
151             break;
152 
153         case 101:
154             pWkstaInfo = midl_user_allocate(sizeof(WKSTA_INFO_101));
155             if (pWkstaInfo == NULL)
156             {
157                 dwResult = ERROR_NOT_ENOUGH_MEMORY;
158                 break;
159             }
160 
161             pWkstaInfo->WkstaInfo101.wki101_platform_id = PLATFORM_ID_NT;
162 
163             pWkstaInfo->WkstaInfo101.wki101_computername = midl_user_allocate(dwComputerNameLength * sizeof(WCHAR));
164             if (pWkstaInfo->WkstaInfo101.wki101_computername != NULL)
165                 wcscpy(pWkstaInfo->WkstaInfo101.wki101_computername, szComputerName);
166 
167             pWkstaInfo->WkstaInfo101.wki101_langroup = midl_user_allocate((wcslen(DomainInfo->Name.Buffer) + 1) * sizeof(WCHAR));
168             if (pWkstaInfo->WkstaInfo101.wki101_langroup != NULL)
169                 wcscpy(pWkstaInfo->WkstaInfo101.wki101_langroup, DomainInfo->Name.Buffer);
170 
171             pWkstaInfo->WkstaInfo101.wki101_ver_major = VersionInfo.dwMajorVersion;
172             pWkstaInfo->WkstaInfo101.wki101_ver_minor = VersionInfo.dwMinorVersion;
173 
174             pWkstaInfo->WkstaInfo101.wki101_lanroot = midl_user_allocate((wcslen(pszLanRoot) + 1) * sizeof(WCHAR));
175             if (pWkstaInfo->WkstaInfo101.wki101_lanroot != NULL)
176                 wcscpy(pWkstaInfo->WkstaInfo101.wki101_lanroot, pszLanRoot);
177 
178             *WkstaInfo = pWkstaInfo;
179             break;
180 
181         case 102:
182             pWkstaInfo = midl_user_allocate(sizeof(WKSTA_INFO_102));
183             if (pWkstaInfo == NULL)
184             {
185                 dwResult = ERROR_NOT_ENOUGH_MEMORY;
186                 break;
187             }
188 
189             pWkstaInfo->WkstaInfo102.wki102_platform_id = PLATFORM_ID_NT;
190 
191             pWkstaInfo->WkstaInfo102.wki102_computername = midl_user_allocate(dwComputerNameLength * sizeof(WCHAR));
192             if (pWkstaInfo->WkstaInfo102.wki102_computername != NULL)
193                 wcscpy(pWkstaInfo->WkstaInfo102.wki102_computername, szComputerName);
194 
195             pWkstaInfo->WkstaInfo102.wki102_langroup = midl_user_allocate((wcslen(DomainInfo->Name.Buffer) + 1) * sizeof(WCHAR));
196             if (pWkstaInfo->WkstaInfo102.wki102_langroup != NULL)
197                 wcscpy(pWkstaInfo->WkstaInfo102.wki102_langroup, DomainInfo->Name.Buffer);
198 
199             pWkstaInfo->WkstaInfo102.wki102_ver_major = VersionInfo.dwMajorVersion;
200             pWkstaInfo->WkstaInfo102.wki102_ver_minor = VersionInfo.dwMinorVersion;
201 
202             pWkstaInfo->WkstaInfo102.wki102_lanroot = midl_user_allocate((wcslen(pszLanRoot) + 1) * sizeof(WCHAR));
203             if (pWkstaInfo->WkstaInfo102.wki102_lanroot != NULL)
204                 wcscpy(pWkstaInfo->WkstaInfo102.wki102_lanroot, pszLanRoot);
205 
206             pWkstaInfo->WkstaInfo102.wki102_logged_on_users = 1; /* FIXME */
207 
208             *WkstaInfo = pWkstaInfo;
209             break;
210 
211         default:
212             FIXME("Level %d unimplemented\n", Level);
213             dwResult = ERROR_INVALID_LEVEL;
214             break;
215     }
216 
217     if (DomainInfo != NULL)
218         LsaFreeMemory(DomainInfo);
219 
220     return dwResult;
221 }
222 
223 
224 /* Function 1 */
225 unsigned long
226 __stdcall
227 NetrWkstaSetInfo(
228     WKSSVC_IDENTIFY_HANDLE ServerName,
229     unsigned long Level,
230     LPWKSTA_INFO WkstaInfo,
231     unsigned long *ErrorParameter)
232 {
233     UNIMPLEMENTED;
234     return 0;
235 }
236 
237 
238 /* Function 2 */
239 unsigned long
240 __stdcall
241 NetrWkstaUserEnum(
242     WKSSVC_IDENTIFY_HANDLE ServerName,
243     LPWKSTA_USER_ENUM_STRUCT UserInfo,
244     unsigned long PreferredMaximumLength,
245     unsigned long *TotalEntries,
246     unsigned long *ResumeHandle)
247 {
248     ERR("NetrWkstaUserEnum(%p %p 0x%lx %p %p)\n",
249         ServerName, UserInfo, PreferredMaximumLength, TotalEntries, ResumeHandle);
250 
251 
252     UNIMPLEMENTED;
253     return 0;
254 }
255 
256 
257 /* Function 3 */
258 unsigned long
259 __stdcall
260 NetrWkstaUserGetInfo(
261     WKSSVC_IDENTIFY_HANDLE Unused,
262     unsigned long Level,
263     LPWKSTA_USER_INFO UserInfo)
264 {
265     FIXME("(%s, %d, %p)\n", debugstr_w(Unused), Level, UserInfo);
266 
267     UNIMPLEMENTED;
268     return 0;
269 }
270 
271 
272 /* Function 4 */
273 unsigned long
274 __stdcall
275 NetrWkstaUserSetInfo (
276     WKSSVC_IDENTIFY_HANDLE Unused,
277     unsigned long Level,
278     LPWKSTA_USER_INFO UserInfo,
279     unsigned long *ErrorParameter)
280 {
281     UNIMPLEMENTED;
282     return 0;
283 }
284 
285 
286 /* Function 5 */
287 unsigned long
288 __stdcall
289 NetrWkstaTransportEnum(
290     WKSSVC_IDENTIFY_HANDLE ServerName,
291     LPWKSTA_TRANSPORT_ENUM_STRUCT TransportInfo,
292     unsigned long PreferredMaximumLength,
293     unsigned long* TotalEntries,
294     unsigned long *ResumeHandle)
295 {
296     UNIMPLEMENTED;
297     return 0;
298 }
299 
300 
301 /* Function 6 */
302 unsigned long
303 __stdcall
304 NetrWkstaTransportAdd(
305     WKSSVC_IDENTIFY_HANDLE ServerName,
306     unsigned long Level,
307     LPWKSTA_TRANSPORT_INFO_0 TransportInfo,
308     unsigned long *ErrorParameter)
309 {
310     UNIMPLEMENTED;
311     return 0;
312 }
313 
314 
315 /* Function 7 */
316 unsigned long
317 __stdcall
318 NetrWkstaTransportDel(
319     WKSSVC_IDENTIFY_HANDLE ServerName,
320     wchar_t *TransportName,
321     unsigned long ForceLevel)
322 {
323     UNIMPLEMENTED;
324     return 0;
325 }
326 
327 
328 /* Function 8 */
329 unsigned long
330 __stdcall
331 NetrUseAdd(
332     WKSSVC_IMPERSONATE_HANDLE ServerName,
333     unsigned long Level,
334     LPUSE_INFO InfoStruct,
335     unsigned long *ErrorParameter)
336 {
337     UNIMPLEMENTED;
338     return 0;
339 }
340 
341 
342 /* Function 9 */
343 unsigned long
344 __stdcall
345 NetrUseGetInfo(
346     WKSSVC_IMPERSONATE_HANDLE ServerName,
347     wchar_t *UseName,
348     unsigned long Level,
349     LPUSE_INFO InfoStruct)
350 {
351     UNIMPLEMENTED;
352     return 0;
353 }
354 
355 
356 /* Function 10 */
357 unsigned long
358 __stdcall
359 NetrUseDel(
360     WKSSVC_IMPERSONATE_HANDLE ServerName,
361     wchar_t *UseName,
362     unsigned long ForceLevel)
363 {
364     UNIMPLEMENTED;
365     return 0;
366 }
367 
368 
369 /* Function 11 */
370 unsigned long
371 __stdcall
372 NetrUseEnum(
373     WKSSVC_IDENTIFY_HANDLE ServerName,
374     LPUSE_ENUM_STRUCT InfoStruct,
375     unsigned long PreferredMaximumLength,
376     unsigned long *TotalEntries,
377     unsigned long *ResumeHandle)
378 {
379     UNIMPLEMENTED;
380     return 0;
381 }
382 
383 
384 /* Function 12 - Not used on wire */
385 unsigned long
386 __stdcall
387 NetrMessageBufferSend(void)
388 {
389     TRACE("NetrMessageBufferSend()\n");
390     return ERROR_NOT_SUPPORTED;
391 }
392 
393 
394 /* Function 13 */
395 unsigned long
396 __stdcall
397 NetrWorkstationStatisticsGet(
398     WKSSVC_IDENTIFY_HANDLE ServerName,
399     wchar_t *ServiceName,
400     unsigned long Level,
401     unsigned long Options,
402     LPSTAT_WORKSTATION_0 *Buffer)
403 {
404     PSTAT_WORKSTATION_0 pStatBuffer;
405 
406     TRACE("NetrWorkstationStatisticsGet(%p %p %lu 0x%lx %p)\n",
407           ServerName, ServiceName, Level, Options, Buffer);
408 
409     if (Level != 0)
410         return ERROR_INVALID_LEVEL;
411 
412     if (Options != 0)
413         return ERROR_INVALID_PARAMETER;
414 
415     pStatBuffer = midl_user_allocate(sizeof(STAT_WORKSTATION_0));
416     if (pStatBuffer == NULL)
417         return ERROR_NOT_ENOUGH_MEMORY;
418 
419     ZeroMemory(pStatBuffer, sizeof(STAT_WORKSTATION_0));
420 
421     // FIXME: Return the actual statistcs data!
422 
423     *Buffer = pStatBuffer;
424 
425     return NERR_Success;
426 }
427 
428 
429 /* Function 14 - Not used on wire */
430 unsigned long
431 __stdcall
432 NetrLogonDomainNameAdd(
433     WKSSVC_IDENTIFY_HANDLE DomainName)
434 {
435     TRACE("NetrLogonDomainNameAdd(%s)\n",
436           debugstr_w(DomainName));
437     return ERROR_NOT_SUPPORTED;
438 }
439 
440 
441 /* Function 15 - Not used on wire */
442 unsigned long
443 __stdcall
444 NetrLogonDomainNameDel(
445     WKSSVC_IDENTIFY_HANDLE DomainName)
446 {
447     TRACE("NetrLogonDomainNameDel(%s)\n",
448           debugstr_w(DomainName));
449     return ERROR_NOT_SUPPORTED;
450 }
451 
452 
453 /* Function 16 - Not used on wire */
454 unsigned long
455 __stdcall
456 NetrJoinDomain(void)
457 {
458     TRACE("NetrJoinDomain()\n");
459     return ERROR_NOT_SUPPORTED;
460 }
461 
462 
463 /* Function 17 - Not used on wire */
464 unsigned long
465 __stdcall
466 NetrUnjoinDomain(void)
467 {
468     TRACE("NetrUnjoinDomain()\n");
469     return ERROR_NOT_SUPPORTED;
470 }
471 
472 
473 /* Function 18 - Not used on wire */
474 unsigned long
475 __stdcall
476 NetrValidateName(void)
477 {
478     TRACE("NetrValidateName()\n");
479     return ERROR_NOT_SUPPORTED;
480 }
481 
482 
483 /* Function 19 - Not used on wire */
484 unsigned long
485 __stdcall
486 NetrRenameMachineInDomain(void)
487 {
488     TRACE("NetrRenameMachineInDomain()\n");
489     return ERROR_NOT_SUPPORTED;
490 }
491 
492 
493 /* Function 20 */
494 unsigned long
495 __stdcall
496 NetrGetJoinInformation(
497     WKSSVC_IMPERSONATE_HANDLE ServerName,
498     wchar_t **NameBuffer,
499     PNETSETUP_JOIN_STATUS BufferType)
500 {
501     TRACE("NetrGetJoinInformation(%p %p %p)\n",
502           ServerName, NameBuffer, BufferType);
503 
504     if (NameBuffer == NULL)
505         return ERROR_INVALID_PARAMETER;
506 
507     return NetpGetJoinInformation(NameBuffer,
508                                   BufferType);
509 }
510 
511 
512 /* Function 21 - Not used on wire */
513 unsigned long
514 __stdcall
515 NetrGetJoinableOUs(void)
516 {
517     TRACE("NetrGetJoinableOUs()\n");
518     return ERROR_NOT_SUPPORTED;
519 }
520 
521 
522 /* Function 22 */
523 unsigned long
524 __stdcall
525 NetrJoinDomain2(
526     handle_t RpcBindingHandle,
527     wchar_t *ServerName,
528     wchar_t *DomainNameParam,
529     wchar_t *MachineAccountOU,
530     wchar_t *AccountName,
531     PJOINPR_ENCRYPTED_USER_PASSWORD Password,
532     unsigned long Options)
533 {
534     NET_API_STATUS status;
535 
536     FIXME("NetrJoinDomain2(%p %S %S %S %S %p 0x%lx)\n",
537           RpcBindingHandle, ServerName, DomainNameParam, MachineAccountOU,
538           AccountName, Password, Options);
539 
540     if (DomainNameParam == NULL)
541         return ERROR_INVALID_PARAMETER;
542 
543     if (Options & NETSETUP_JOIN_DOMAIN)
544     {
545         FIXME("NetrJoinDomain2: NETSETUP_JOIN_DOMAIN is not supported yet!\n");
546         status = ERROR_CALL_NOT_IMPLEMENTED;
547     }
548     else
549     {
550         status = NetpJoinWorkgroup(DomainNameParam);
551     }
552 
553     return status;
554 }
555 
556 
557 /* Function 23 */
558 unsigned long
559 __stdcall
560 NetrUnjoinDomain2(
561     handle_t RpcBindingHandle,
562     wchar_t *ServerName,
563     wchar_t *AccountName,
564     PJOINPR_ENCRYPTED_USER_PASSWORD Password,
565     unsigned long Options)
566 {
567     UNIMPLEMENTED;
568     return 0;
569 }
570 
571 
572 /* Function 24 */
573 unsigned long
574 __stdcall
575 NetrRenameMachineInDomain2(
576     handle_t RpcBindingHandle,
577     wchar_t *ServerName,
578     wchar_t *MachineName,
579     wchar_t *AccountName,
580     PJOINPR_ENCRYPTED_USER_PASSWORD Password,
581     unsigned long Options)
582 {
583     UNIMPLEMENTED;
584     return 0;
585 }
586 
587 
588 /* Function 25 */
589 unsigned long
590 __stdcall
591 NetrValidateName2(
592     handle_t RpcBindingHandle,
593     wchar_t *ServerName,
594     wchar_t *NameToValidate,
595     wchar_t *AccountName,
596     PJOINPR_ENCRYPTED_USER_PASSWORD Password,
597     NETSETUP_NAME_TYPE NameType)
598 {
599     UNIMPLEMENTED;
600     return 0;
601 }
602 
603 
604 /* Function 26 */
605 unsigned long
606 __stdcall
607 NetrGetJoinableOUs2(
608     handle_t RpcBindingHandle,
609     wchar_t *ServerName,
610     wchar_t *DomainNameParam,
611     wchar_t *AccountName,
612     PJOINPR_ENCRYPTED_USER_PASSWORD Password,
613     unsigned long* OUCount,
614     wchar_t ***OUs)
615 {
616     UNIMPLEMENTED;
617     return 0;
618 }
619 
620 
621 /* Function 27 */
622 unsigned long
623 __stdcall
624 NetrAddAlternateComputerName(
625     handle_t RpcBindingHandle,
626     wchar_t *ServerName,
627     wchar_t *AlternateName,
628     wchar_t *DomainAccount,
629     PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword,
630     unsigned long Reserved)
631 {
632     UNIMPLEMENTED;
633     return 0;
634 }
635 
636 
637 /* Function 28 */
638 unsigned long
639 __stdcall
640 NetrRemoveAlternateComputerName(
641     handle_t RpcBindingHandle,
642     wchar_t *ServerName,
643     wchar_t *AlternateName,
644     wchar_t *DomainAccount,
645     PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword,
646     unsigned long Reserved)
647 {
648     UNIMPLEMENTED;
649     return 0;
650 }
651 
652 
653 /* Function 29 */
654 unsigned long
655 __stdcall
656 NetrSetPrimaryComputerName(
657     handle_t RpcBindingHandle,
658     wchar_t *ServerName,
659     wchar_t *PrimaryName,
660     wchar_t *DomainAccount,
661     PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword,
662     unsigned long Reserved)
663 {
664     UNIMPLEMENTED;
665     return 0;
666 }
667 
668 
669 /* Function 30 */
670 unsigned long
671 __stdcall
672 NetrEnumerateComputerNames(
673     WKSSVC_IMPERSONATE_HANDLE ServerName,
674     NET_COMPUTER_NAME_TYPE NameType,
675     unsigned long Reserved,
676     PNET_COMPUTER_NAME_ARRAY *ComputerNames)
677 {
678     UNIMPLEMENTED;
679     return 0;
680 }
681 
682 /* EOF */
683