2c8f462e40215c91ec7b5bcaf21b531d9b9a392d
[openafs.git] / src / WINNT / afsd / rpc_srvsvc.c
1 /*
2  * Copyright (c) 2009 Secure Endpoints Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25
26 #include <afsconfig.h>
27 #include <afs/param.h>
28 #include <roken.h>
29
30 #include<windows.h>
31 #include <wchar.h>
32 #define _CRT_RAND_S
33 #include <stdlib.h>
34 #include <strsafe.h>
35 #include <svrapi.h>
36 #include "ms-srvsvc.h"
37 #include "msrpc.h"
38 #include "afsd.h"
39 #include "smb.h"
40 #include <WINNT/afsreg.h>
41 #define AFS_VERSION_STRINGS
42 #include "AFS_component_version_number.h"
43
44 #pragma warning( disable: 4027 )  /* func w/o formal parameter list */
45
46 /* Do not pull in lmserver.h */
47 //
48 // The platform ID indicates the levels to use for platform-specific
49 // information.
50 //
51 #define SV_PLATFORM_ID_DOS 300
52 #define SV_PLATFORM_ID_OS2 400
53 #define SV_PLATFORM_ID_NT  500
54 #define SV_PLATFORM_ID_OSF 600
55 #define SV_PLATFORM_ID_VMS 700
56 #define SV_PLATFORM_ID_AFS 800
57 //
58 //      Bit-mapped values for svX_type fields. X = 1, 2 or 3.
59 //
60 #define SV_TYPE_WORKSTATION         0x00000001
61 #define SV_TYPE_SERVER              0x00000002
62 #define SV_TYPE_SQLSERVER           0x00000004
63 #define SV_TYPE_DOMAIN_CTRL         0x00000008
64 #define SV_TYPE_DOMAIN_BAKCTRL      0x00000010
65 #define SV_TYPE_TIME_SOURCE         0x00000020
66 #define SV_TYPE_AFP                 0x00000040
67 #define SV_TYPE_NOVELL              0x00000080
68 #define SV_TYPE_DOMAIN_MEMBER       0x00000100
69 #define SV_TYPE_PRINTQ_SERVER       0x00000200
70 #define SV_TYPE_DIALIN_SERVER       0x00000400
71 #define SV_TYPE_XENIX_SERVER        0x00000800
72 #define SV_TYPE_SERVER_UNIX         SV_TYPE_XENIX_SERVER
73 #define SV_TYPE_NT                  0x00001000
74 #define SV_TYPE_WFW                 0x00002000
75 #define SV_TYPE_SERVER_MFPN         0x00004000
76 #define SV_TYPE_SERVER_NT           0x00008000
77 #define SV_TYPE_POTENTIAL_BROWSER   0x00010000
78 #define SV_TYPE_BACKUP_BROWSER      0x00020000
79 #define SV_TYPE_MASTER_BROWSER      0x00040000
80 #define SV_TYPE_DOMAIN_MASTER       0x00080000
81 #define SV_TYPE_SERVER_OSF          0x00100000
82 #define SV_TYPE_SERVER_VMS          0x00200000
83 #define SV_TYPE_WINDOWS             0x00400000  /* Windows95 and above */
84 #define SV_TYPE_DFS                 0x00800000  /* Root of a DFS tree */
85 #define SV_TYPE_CLUSTER_NT          0x01000000  /* NT Cluster */
86 #define SV_TYPE_TERMINALSERVER      0x02000000  /* Terminal Server(Hydra) */
87 #define SV_TYPE_CLUSTER_VS_NT       0x04000000  /* NT Cluster Virtual Server Name */
88 #define SV_TYPE_DCE                 0x10000000  /* IBM DSS (Directory and Security Services) or equivalent */
89 #define SV_TYPE_ALTERNATE_XPORT     0x20000000  /* return list for alternate transport */
90 #define SV_TYPE_LOCAL_LIST_ONLY     0x40000000  /* Return local list only */
91 #define SV_TYPE_DOMAIN_ENUM         0x80000000
92 #define SV_TYPE_ALL                 0xFFFFFFFF  /* handy for NetServerEnum2 */
93 //
94 //      Values of svX_hidden field. X = 2 or 3.
95 //
96 #define SV_HIDDEN       1
97 #define SV_VISIBLE      0
98
99 NET_API_STATUS NetrConnectionEnum(
100     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
101     /* [unique][string][in] */ WCHAR *Qualifier,
102     /* [out][in] */ LPCONNECT_ENUM_STRUCT InfoStruct,
103     /* [in] */ DWORD PreferedMaximumLength,
104     /* [out] */ DWORD *TotalEntries,
105     /* [unique][out][in] */ DWORD *ResumeHandle)
106 {
107     osi_Log0(afsd_logp, "NetrConnectionEnum not supported");
108     return ERROR_NOT_SUPPORTED;
109 }
110
111 NET_API_STATUS NetrFileEnum(
112     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
113     /* [unique][string][in] */ WCHAR *BasePath,
114     /* [unique][string][in] */ WCHAR *UserName,
115     /* [out][in] */ PFILE_ENUM_STRUCT InfoStruct,
116     /* [in] */ DWORD PreferedMaximumLength,
117     /* [out] */ DWORD *TotalEntries,
118     /* [unique][out][in] */ DWORD *ResumeHandle)
119 {
120     osi_Log0(afsd_logp, "NetrFileEnum not supported");
121     return ERROR_NOT_SUPPORTED;
122 }
123
124 NET_API_STATUS NetrFileGetInfo(
125     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
126     /* [in] */ DWORD FileId,
127     /* [in] */ DWORD Level,
128     /* [switch_is][out] */ LPFILE_INFO InfoStruct)
129 {
130     osi_Log0(afsd_logp, "NetrFileGetInfo not supported");
131     return ERROR_NOT_SUPPORTED;
132 }
133
134 NET_API_STATUS NetrFileClose(
135     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
136     /* [in] */ DWORD FileId)
137 {
138     osi_Log0(afsd_logp, "NetrFileClose not supported");
139     return ERROR_NOT_SUPPORTED;
140 }
141
142 NET_API_STATUS NetrSessionEnum(
143     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
144     /* [unique][string][in] */ WCHAR *ClientName,
145     /* [unique][string][in] */ WCHAR *UserName,
146     /* [out][in] */ PSESSION_ENUM_STRUCT InfoStruct,
147     /* [in] */ DWORD PreferedMaximumLength,
148     /* [out] */ DWORD *TotalEntries,
149     /* [unique][out][in] */ DWORD *ResumeHandle)
150 {
151     osi_Log0(afsd_logp, "NetrSessionEnum not supported");
152     return ERROR_NOT_SUPPORTED;
153 }
154
155 NET_API_STATUS NetrSessionDel(
156     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
157     /* [unique][string][in] */ WCHAR *ClientName,
158     /* [unique][string][in] */ WCHAR *UserName)
159 {
160     osi_Log0(afsd_logp, "NetrSessionDel not supported");
161     return ERROR_NOT_SUPPORTED;
162 }
163
164 NET_API_STATUS NetrShareAdd(
165     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
166     /* [in] */ DWORD Level,
167     /* [switch_is][in] */ LPSHARE_INFO InfoStruct,
168     /* [unique][out][in] */ DWORD *ParmErr)
169 {
170     osi_Log0(afsd_logp, "NetrShareAdd not supported");
171     return ERROR_NOT_SUPPORTED;
172 }
173
174 static wchar_t *
175 NetrIntGenerateShareRemark(cm_scache_t *scp, cm_fid_t *fidp)
176 {
177     wchar_t remark[1536], *s, *wcellname, *wmp;
178     HRESULT hr;
179     cm_cell_t *cellp;
180     afs_int32 b;
181
182     cellp = cm_FindCellByID(fidp->cell, CM_FLAG_NOPROBE);
183
184     if (cellp)
185         wcellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL);
186     else
187         wcellname = L"";
188
189     if (scp) {
190         switch (scp->fileType) {
191         case 1:
192             hr = StringCchPrintfW( remark,
193                                    sizeof(remark)/sizeof(remark[0]),
194                                    L"AFS File (%s:%u.%u.%u)",
195                                    wcellname,
196                                    scp->fid.volume,
197                                    scp->fid.vnode, scp->fid.unique);
198             if (hr == S_OK)
199                 s = wcsdup(remark);
200             else
201                 s = wcsdup(L"AFS File");
202             break;
203         case 2:
204             hr = StringCchPrintfW( remark,
205                                    sizeof(remark)/sizeof(remark[0]),
206                                    L"AFS Directory (%s:%u.%u.%u)",
207                                    wcellname,
208                                    scp->fid.volume,
209                                    scp->fid.vnode, scp->fid.unique);
210             if (hr == S_OK)
211                 s = wcsdup(remark);
212             else
213                 s = wcsdup(L"AFS Directory");
214             break;
215         case 3:
216             wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL);
217             hr = StringCchPrintfW( remark,
218                                    sizeof(remark)/sizeof(remark[0]),
219                                    L"AFS Symlink to %s",
220                                    wmp ? wmp : L"");
221             if (hr == S_OK)
222                 s = wcsdup(remark);
223             else
224                 s = wcsdup(L"AFS Symlink");
225             if (wmp)
226                 free(wmp);
227             break;
228         case 4:
229             b = (strchr(scp->mountPointStringp, ':') != NULL);
230             wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL);
231             hr = StringCchPrintfW( remark,
232                                    sizeof(remark)/sizeof(remark[0]),
233                                    L"AFS MountPoint to %s%s%s%s",
234                                    wmp ? wmp : L"",
235                                    b ? L"" : L" (",
236                                    b ? L"" : wcellname,
237                                    b ? L"" : L")");
238             if (hr == S_OK)
239                 s = wcsdup(remark);
240             else
241                 s = wcsdup(L"AFS MountPoint");
242             if (wmp)
243                 free(wmp);
244             break;
245         case 5:
246             wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL);
247             hr = StringCchPrintfW( remark,
248                                    sizeof(remark)/sizeof(remark[0]),
249                                    L"AFS Dfslink to %s",
250                                    wmp ? wmp : L"");
251             if (hr == S_OK)
252                 s = wcsdup(remark);
253             else
254                 s = wcsdup(L"AFS DfsLink");
255             if (wmp)
256                 free(wmp);
257             break;
258         default:
259             hr = StringCchPrintfW( remark,
260                                    sizeof(remark)/sizeof(remark[0]),
261                                    L"AFS Object (%s:%u.%u.%u)",
262                                    wcellname,
263                                    scp->fid.volume,
264                                    scp->fid.vnode, scp->fid.unique);
265             if (hr == S_OK)
266                 s = wcsdup(remark);
267             else
268                 s = wcsdup(L"AFS Object");
269         }
270     } else {
271         if (fidp->vnode & 1) {
272             hr = StringCchPrintfW( remark,
273                                    sizeof(remark)/sizeof(remark[0]),
274                                    L"AFS Directory (%s:%u.%u.%u)",
275                                    wcellname,
276                                    fidp->volume,
277                                    fidp->vnode, fidp->unique);
278             if (hr == S_OK)
279                 s = wcsdup(remark);
280             else
281                 s = wcsdup(L"AFS Directory");
282         } else {
283             hr = StringCchPrintfW( remark,
284                                    sizeof(remark)/sizeof(remark[0]),
285                                    L"AFS Object (%s:%u.%u.%u)",
286                                    wcellname,
287                                    fidp->volume,
288                                    fidp->vnode, fidp->unique);
289             if (hr == S_OK)
290                 s = wcsdup(remark);
291             else
292                 s = wcsdup(L"AFS Object");
293         }
294     }
295     if (cellp && wcellname)
296         free(wcellname);
297     return s;
298 }
299
300 static wchar_t *
301 NetrIntGenerateSharePath(wchar_t *ServerName, cm_fid_t *fidp)
302 {
303     wchar_t remark[1536], *s, *wcellname;
304     HRESULT hr;
305     cm_cell_t *cellp;
306
307     cellp = cm_FindCellByID(fidp->cell, CM_FLAG_NOPROBE);
308
309     if (cellp)
310         wcellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL);
311     else
312         wcellname = L"";
313
314     for ( s=ServerName; *s == '\\' || *s == '/'; s++);
315     hr = StringCchPrintfW( remark,
316                            sizeof(remark)/sizeof(remark[0]),
317                            L"\\\\%s\\%s\\%u.%u.%u",
318                            s, wcellname,
319                            fidp->volume,
320                            fidp->vnode, fidp->unique);
321     if (hr == S_OK)
322         s = wcsdup(remark);
323     else
324         s = wcsdup(L"");
325
326     if (cellp && wcellname)
327         free(wcellname);
328     return s;
329 }
330
331 typedef struct netr_share_enum {
332     osi_queue_t   q;
333     time_t        cleanup_time;
334     DWORD         handle;
335     cm_direnum_t *direnump;
336 } netr_share_enum_t;
337
338 static osi_queue_t * shareEnumQ = NULL;
339 static osi_mutex_t   shareEnum_mx;
340 static DWORD         shareEnum_next_handle=1;
341
342 void
343 RPC_SRVSVC_Init(void)
344 {
345 #if _MSC_VER >= 1400
346     int hasRand_s = -1;
347     OSVERSIONINFO osInfo;
348
349     osInfo.dwOSVersionInfoSize = sizeof(osInfo);
350     if (GetVersionEx(&osInfo)) {
351         if ((osInfo.dwMajorVersion > 5) ||
352              (osInfo.dwMajorVersion == 5) && (osInfo.dwMinorVersion >= 1))
353             hasRand_s = 1;
354         else
355             hasRand_s = 0;
356     }
357 #endif
358
359     lock_InitializeMutex(&shareEnum_mx, "NetrShareEnum", 0);
360     shareEnumQ = NULL;
361 #if _MSC_VER >= 1400
362     if (hasRand_s > 0) {
363         rand_s(&shareEnum_next_handle);
364     } else
365 #endif
366     {
367         srand((unsigned) time( NULL ));
368         shareEnum_next_handle = rand();
369     }
370 }
371
372 void
373 RPC_SRVSVC_Shutdown(void)
374 {
375     netr_share_enum_t *enump;
376
377     lock_ObtainMutex(&shareEnum_mx);
378     while (shareEnumQ) {
379         enump = (netr_share_enum_t *)shareEnumQ;
380         cm_BPlusDirFreeEnumeration(enump->direnump);
381         osi_QRemove(&shareEnumQ, (osi_queue_t *)enump);
382         free(enump);
383     }
384     lock_FinalizeMutex(&shareEnum_mx);
385 }
386
387 static void
388 RPC_SRVSVC_ShareEnumAgeCheck(void) {
389     netr_share_enum_t *enump, *enumnp;
390     time_t            now;
391
392     lock_ObtainMutex(&shareEnum_mx);
393     now = time(NULL);
394     for (enump = (netr_share_enum_t *)shareEnumQ;
395          enump; enump = enumnp) {
396         enumnp = (netr_share_enum_t *) osi_QNext(&(enump->q));
397         if (now > enump->cleanup_time)
398             osi_QRemove(&shareEnumQ, (osi_queue_t *)enump);
399     }
400     lock_ReleaseMutex(&shareEnum_mx);
401 }
402
403 static cm_direnum_t *
404 RPC_SRVSVC_ShareEnumFind(DWORD ResumeHandle) {
405     netr_share_enum_t *enump;
406
407     lock_ObtainMutex(&shareEnum_mx);
408     for (enump = (netr_share_enum_t *)shareEnumQ;
409          enump;
410          enump = (netr_share_enum_t *) osi_QNext(&enump->q)) {
411         if (ResumeHandle == enump->handle)
412             break;
413     }
414     lock_ReleaseMutex(&shareEnum_mx);
415
416     return enump ? enump->direnump : NULL;
417 }
418
419 static DWORD
420 RPC_SRVSVC_ShareEnumSave(cm_direnum_t *direnump) {
421     netr_share_enum_t *enump = (netr_share_enum_t *)malloc(sizeof(netr_share_enum_t));
422
423     if (enump == NULL)
424         return 0xFFFFFFFF;
425
426     lock_ObtainMutex(&shareEnum_mx);
427     enump->cleanup_time = time(NULL) + 300;
428     enump->handle = shareEnum_next_handle++;
429     if (shareEnum_next_handle == 0xFFFFFFFF)
430         shareEnum_next_handle = 1;
431     enump->direnump = direnump;
432     osi_QAdd(&shareEnumQ, (osi_queue_t *)enump);
433     lock_ReleaseMutex(&shareEnum_mx);
434
435     return enump->handle;
436 }
437
438 static void
439 RPC_SRVSVC_ShareEnumRemove(cm_direnum_t *direnump) {
440     netr_share_enum_t *enump;
441
442     lock_ObtainMutex(&shareEnum_mx);
443     for (enump = (netr_share_enum_t *)shareEnumQ;
444          enump;
445          enump = (netr_share_enum_t *) osi_QNext(&enump->q)) {
446         if (direnump == enump->direnump) {
447             osi_QRemove(&shareEnumQ, (osi_queue_t *)enump);
448             break;
449         }
450     }
451     lock_ReleaseMutex(&shareEnum_mx);
452 }
453
454 NET_API_STATUS NetrShareEnum(
455     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
456     /* [out][in] */ LPSHARE_ENUM_STRUCT InfoStruct,
457     /* [in] */ DWORD PreferedMaximumLength,
458     /* [out] */ DWORD *TotalEntries,
459     /* [unique][out][in] */ DWORD *ResumeHandle)
460 {
461     cm_direnum_t *enump = NULL;
462     cm_direnum_entry_t * entryp = NULL;
463     cm_scache_t * dscp;
464     cm_user_t *userp = MSRPC_GetCmUser();
465     cm_req_t      req;
466     int           stopnow = 0;
467     afs_uint32    count = 0;
468     afs_uint32    code;
469     afs_uint32    old_enum = 0;
470     size_t        space_limited = 0;
471     size_t        space_available = 0;
472     afs_uint32    first_entry = 1;
473
474     osi_Log1(afsd_logp, "NetrShareEnum level %u", InfoStruct->Level);
475
476     cm_InitReq(&req);
477
478     dscp = cm_RootSCachep(userp, &req);
479
480     RPC_SRVSVC_ShareEnumAgeCheck();
481
482     /* We only support one server name so ignore 'ServerName'. */
483
484     /* Test for unsupported level early */
485     switch (InfoStruct->Level) {
486     case 2:
487     case 1:
488     case 0:
489         break;
490     default:
491         return ERROR_INVALID_LEVEL;
492     }
493
494     if (ResumeHandle && *ResumeHandle == 0xFFFFFFFF) {
495         /* No More Entries */
496         InfoStruct->ShareInfo.Level0->EntriesRead = 0;
497         return ERROR_NO_MORE_FILES;
498     }
499
500     /* get the directory size */
501     cm_HoldSCache(dscp);
502     lock_ObtainWrite(&dscp->rw);
503     code = cm_SyncOp(dscp, NULL, userp, &req, PRSFS_LOOKUP,
504                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
505     if (code) {
506         lock_ReleaseWrite(&dscp->rw);
507         cm_ReleaseSCache(dscp);
508         osi_Log1(afsd_logp, "NetShareEnum cm_SyncOp failure code=0x%x", code);
509         return ERROR_BUSY;
510     }
511
512     cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
513     lock_ReleaseWrite(&dscp->rw);
514
515     if (dscp->fileType != CM_SCACHETYPE_DIRECTORY) {
516         cm_ReleaseSCache(dscp);
517         osi_Log1(afsd_logp, "NetShareEnum Not a Directory dscp=0x%p", dscp);
518         return ERROR_DIRECTORY;
519     }
520
521     /*
522      * If there is no enumeration handle, then this is a new query
523      * and we must perform an enumeration for the specified object
524      */
525     if (ResumeHandle == NULL || *ResumeHandle == 0) {
526         cm_dirOp_t    dirop;
527
528         code = cm_BeginDirOp(dscp, userp, &req, CM_DIRLOCK_READ,
529                              CM_DIROP_FLAG_NONE, &dirop);
530         if (code == 0) {
531             code = cm_BPlusDirEnumerate(dscp, userp, &req, TRUE, NULL, TRUE, &enump);
532             if (code) {
533                 osi_Log1(afsd_logp, "NetShareEnum cm_BPlusDirEnumerate failure code=0x%x",
534                           code);
535             }
536             cm_EndDirOp(&dirop);
537         } else {
538             osi_Log1(afsd_logp, "NetShareEnum cm_BeginDirOp failure code=0x%x",
539                       code);
540         }
541         old_enum = 0;
542     } else {
543         enump = RPC_SRVSVC_ShareEnumFind(*ResumeHandle);
544         old_enum = 1;
545     }
546
547     if (enump == NULL) {
548         cm_ReleaseSCache(dscp);
549         osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present");
550         *TotalEntries = 0;
551         return (code ? ERROR_BUSY : ERROR_SUCCESS);
552     }
553
554     /*
555      * Do not exceed PreferredMaximumLength in any response.
556      * 0xFFFFFFFF means no limit.
557      *
558      * *TotalEntries is a hint of the total entries in the
559      * enumeration.  It does not have to be exact.  It is
560      * the same for each response in an enum.
561      *
562      * If *ResumeHandle == 0, this is an initial call
563      *
564      * The algorithm will be to enumerate the list of share
565      * names based upon the contents of the root.afs root
566      * directory.  We will ignore SMB submount names.
567      * The enumeration will be valid for five minutes.  If
568      * the enumeration is not destroyed within that time period
569      * it will be automatically garbage collected.
570      */
571
572     /*
573      * How much space do we need and do we have that much room?
574      *
575      * If a preferred maximum length is specified, then we must
576      * manage the number of bytes we return in order to restrict
577      * it to a value smaller than then the preferred.  This includes
578      * not only the InfoStruct but also the allocated SHARE_INFO
579      * buffer and the various C strings.  We are not permitted to
580      * send incomplete values so we will send a value that is close.
581      */
582     if (PreferedMaximumLength != 0xFFFFFFFF) {
583         space_limited = 1;
584         space_available =  PreferedMaximumLength;
585     }
586
587     switch (InfoStruct->Level) {
588     case 2:
589         if (space_limited)
590             space_available -= sizeof(InfoStruct->ShareInfo.Level2);
591         InfoStruct->ShareInfo.Level2->Buffer = MIDL_user_allocate((enump->count - enump->next) * sizeof(SHARE_INFO_2));
592         break;
593     case 1:
594         if (space_limited)
595             space_available -= sizeof(InfoStruct->ShareInfo.Level1);
596         InfoStruct->ShareInfo.Level1->Buffer = MIDL_user_allocate((enump->count - enump->next) * sizeof(SHARE_INFO_1));
597         break;
598     case 0:
599         if (space_limited)
600             space_available -= sizeof(InfoStruct->ShareInfo.Level0);
601         InfoStruct->ShareInfo.Level0->Buffer = MIDL_user_allocate((enump->count - enump->next) * sizeof(SHARE_INFO_0));
602         break;
603     }
604
605     if (InfoStruct->ShareInfo.Level0->Buffer == NULL) {
606         cm_ReleaseSCache(dscp);
607         cm_BPlusDirFreeEnumeration(enump);
608         osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present");
609         return ERROR_NOT_ENOUGH_MEMORY;
610     }
611
612     while (!stopnow) {
613         cm_scache_t *scp;
614
615         if (space_limited)
616             code = cm_BPlusDirPeekNextEnumEntry(enump, &entryp);
617         else
618             code = cm_BPlusDirNextEnumEntry(enump, &entryp);
619         if (code != 0 && code != CM_ERROR_STOPNOW || entryp == NULL)
620             break;
621
622         stopnow = (code == CM_ERROR_STOPNOW);
623
624         if ( !wcscmp(L".", entryp->name) || !wcscmp(L"..", entryp->name) ) {
625             osi_Log0(afsd_logp, "NetShareEnum skipping . or ..");
626             if (space_limited)
627                 cm_BPlusDirNextEnumEntry(enump, &entryp);
628             continue;
629         }
630
631         cm_GetSCache(&entryp->fid, NULL, &scp, userp, &req);
632
633         switch (InfoStruct->Level) {
634         case 2:
635             /* for share level security */
636             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_permissions = 0;
637             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_max_uses = -1;
638             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_current_uses = 0;
639             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path =
640                 NetrIntGenerateSharePath(ServerName, &entryp->fid);
641             /* must be the empty string */
642             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_passwd = wcsdup(L"");
643
644             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_type = STYPE_DISKTREE;
645             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark =
646                 NetrIntGenerateShareRemark(scp, &entryp->fid);
647             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname = wcsdup(entryp->name);
648             break;
649         case 1:
650             InfoStruct->ShareInfo.Level1->Buffer[count].shi1_type = STYPE_DISKTREE;
651             InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark =
652                 NetrIntGenerateShareRemark(scp, &entryp->fid);
653             InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname = wcsdup(entryp->name);
654             break;
655         case 0:
656             InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname = wcsdup(entryp->name);
657         }
658
659         if (scp)
660             cm_ReleaseSCache(scp);
661
662         if (space_limited) {
663             size_t space_used;
664             /*
665              * If space is limited, we need to determine if there is room
666              * for the next entry but always send at least one.
667              */
668             switch (InfoStruct->Level) {
669             case 2:
670                 space_used = sizeof(InfoStruct->ShareInfo.Level2->Buffer[count]) +
671                     (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path) + 1) * sizeof(wchar_t) +
672                     sizeof(wchar_t) +  /* passwd */
673                     (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark) + 1) * sizeof(wchar_t) +
674                     (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname) + 1) * sizeof(wchar_t);
675                 break;
676             case 1:
677                 space_used = sizeof(InfoStruct->ShareInfo.Level1->Buffer[count]) +
678                     (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark) + 1) * sizeof(wchar_t) +
679                     (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname) + 1) * sizeof(wchar_t);
680                 break;
681             case 0:
682                 space_used = sizeof(InfoStruct->ShareInfo.Level0->Buffer[count]) +
683                     (wcslen(InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname) + 1) * sizeof(wchar_t);
684                 break;
685             }
686
687             if (!first_entry && space_used > space_available)
688                 break;
689
690             /* Now consume the entry */
691             cm_BPlusDirNextEnumEntry(enump, &entryp);
692             space_available -= space_used;
693         }
694         count++;
695         first_entry = 0;
696     }
697     InfoStruct->ShareInfo.Level0->EntriesRead = count;
698     *TotalEntries = enump->count;
699     if (dscp)
700         cm_ReleaseSCache(dscp);
701
702     if (code || enump->next == enump->count || ResumeHandle == NULL) {
703         if (old_enum)
704             RPC_SRVSVC_ShareEnumRemove(enump);
705         cm_BPlusDirFreeEnumeration(enump);
706         if (ResumeHandle)
707             *ResumeHandle = 0xFFFFFFFF;
708         return (code || enump->next == enump->count) ? 0 : ERROR_MORE_DATA;
709     } else {
710         *ResumeHandle = RPC_SRVSVC_ShareEnumSave(enump);
711         return ERROR_MORE_DATA;
712     }
713 }
714
715 NET_API_STATUS NetrShareGetInfo(
716     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
717     /* [string][in] */ WCHAR *NetName,
718     /* [in] */ DWORD Level,
719     /* [switch_is][out] */ LPSHARE_INFO InfoStruct)
720 {
721     cm_scache_t * dscp;
722     cm_scache_t * scp = NULL;
723     cm_user_t *userp = MSRPC_GetCmUser();
724     cm_req_t      req;
725     afs_uint32    code = 0;
726     NET_API_STATUS status = 0;
727     HKEY parmKey;
728     /* make room for '/@vol:' + mountchar + NULL terminator*/
729     clientchar_t pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH];
730     DWORD  cblen;
731
732     osi_Log1(afsd_logp, "NetrShareGetInfo level %u", Level);
733
734     cm_InitReq(&req);
735
736     dscp = cm_RootSCachep(userp, &req);
737
738     InfoStruct->ShareInfo0 = NULL;
739
740     /*
741      * NetName will be:
742      *  1.a an entry in the root.afs volume root directory
743      *  1.b an entry in the Freelance volume root directory
744      *  2. A volume reference: <cell><type><volume>
745      *  3. an SMB Submount name
746      *  4. a cell name that we do not yet have an entry
747      *     for in the Freelance volume root directory
748      */
749
750     /*
751      * To obtain the needed information for the response we
752      * need to obtain the cm_scache_t entry.  First check to
753      * see if the NetName is a volume reference, then check
754      * if the NetName is an entry in the root volume root
755      * directory, finally we can check the SMB Submounts.
756      * Volume references and SMB submounts are not advertised
757      * as part of the Share enumerations but we should provide
758      * Share info for them nevertheless.  Same for the secret
759      * "all" share.
760      */
761
762     /* Check for volume references
763      *
764      * They look like <cell>{%,#}<volume>
765      */
766     if (cm_ClientStrChr(NetName, '%') != NULL ||
767         cm_ClientStrChr(NetName, '#') != NULL)
768     {
769         osi_Log1(afsd_logp, "NetrShareGetInfo found volume reference [%S]",
770                  osi_LogSaveClientString(afsd_logp, NetName));
771
772         cm_ClientStrPrintfN(pathstr, lengthof(pathstr),
773                             _C(CM_PREFIX_VOL) _C("%s"), NetName);
774         code = cm_Lookup(dscp, pathstr, 0, userp, &req, &scp);
775     } else if (cm_ClientStrCmpI(NetName, L"ALL") == 0) {
776         DWORD allSubmount = 1;
777
778         /* if allSubmounts == 0, only return the //mountRoot/all share
779          * if in fact it has been been created in the subMounts table.
780          * This is to allow sites that want to restrict access to the
781          * world to do so.
782          */
783         code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
784                              0, KEY_QUERY_VALUE, &parmKey);
785         if (code == ERROR_SUCCESS) {
786             cblen = sizeof(allSubmount);
787             code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL,
788                                     (BYTE *) &allSubmount, &cblen);
789             if (code != ERROR_SUCCESS) {
790                 allSubmount = 1;
791             }
792             RegCloseKey (parmKey);
793         }
794
795         if (allSubmount) {
796             scp = dscp;
797             cm_HoldSCache(scp);
798             code = 0;
799         } else {
800             code = CM_ERROR_NOSUCHPATH;
801         }
802     } else {
803         /*
804          * Could be a Submount, a directory entry, or a cell name we
805          * have yet to create an entry for.
806          */
807
808         /* Try a directory entry first */
809         code = cm_Lookup(dscp, NetName, CM_FLAG_NOMOUNTCHASE,
810                           userp, &req, &scp);
811         if (code && code != CM_ERROR_NOACCESS)
812             code = cm_Lookup(dscp, NetName, CM_FLAG_CASEFOLD | CM_FLAG_NOMOUNTCHASE,
813                               userp, &req, &scp);
814
815         if (scp == NULL && code != CM_ERROR_NOACCESS) {  /* Try a submount */
816             code = RegOpenKeyExW(HKEY_LOCAL_MACHINE,  L"Software\\OpenAFS\\Client\\Submounts",
817                                   0, KEY_QUERY_VALUE, &parmKey);
818             if (code == ERROR_SUCCESS) {
819                 cblen = sizeof(pathstr);
820                 code = RegQueryValueExW(parmKey, NetName, NULL, NULL,
821                                          (BYTE *) pathstr, &cblen);
822                 if (code != ERROR_SUCCESS)
823                     cblen = 0;
824                 RegCloseKey (parmKey);
825             } else {
826                 cblen = 0;
827             }
828
829             if (cblen) {
830                 code = cm_NameI(dscp, pathstr, CM_FLAG_FOLLOW, userp, NULL, &req, &scp);
831                 if (code == CM_ERROR_NOSUCHFILE ||
832                     code == CM_ERROR_NOSUCHPATH ||
833                     code == CM_ERROR_BPLUS_NOMATCH)
834                     code = cm_NameI(dscp, pathstr, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
835                                     userp, NULL, &req, &scp);
836             } else {
837                 code = CM_ERROR_NOSUCHPATH;
838             }
839         }
840     }
841
842     if (scp) {
843         /* Allocate the memory for the response */
844         switch (Level) {
845         case 2:
846             InfoStruct->ShareInfo2 = MIDL_user_allocate(sizeof(SHARE_INFO_2));
847             break;
848         case 1:
849             InfoStruct->ShareInfo1 = MIDL_user_allocate(sizeof(SHARE_INFO_1));
850             break;
851         case 0:
852             InfoStruct->ShareInfo0 = MIDL_user_allocate(sizeof(SHARE_INFO_0));
853             break;
854         case 501:
855         case 502:
856         case 503:
857         case 1004:
858         case 1005:
859         case 1006:
860         default:
861             cm_ReleaseSCache(scp);
862             return HRESULT_FROM_WIN32(ERROR_INVALID_LEVEL);
863         }
864
865         if (InfoStruct->ShareInfo0 == NULL) {
866             cm_ReleaseSCache(scp);
867             return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
868         }
869
870         switch (Level) {
871         case 2:
872             /* for share level security */
873             InfoStruct->ShareInfo2->shi2_permissions = 0;
874             InfoStruct->ShareInfo2->shi2_max_uses = -1;
875             InfoStruct->ShareInfo2->shi2_current_uses = 0;
876             InfoStruct->ShareInfo2->shi2_path =
877                 NetrIntGenerateSharePath(ServerName, &scp->fid);
878             /* must be the empty string */
879             InfoStruct->ShareInfo2->shi2_passwd = wcsdup(L"");
880             /* fall-through */
881         case 1:
882             InfoStruct->ShareInfo1->shi1_type = STYPE_DISKTREE;
883             InfoStruct->ShareInfo1->shi1_remark =
884                 NetrIntGenerateShareRemark(scp, &scp->fid);
885             /* fall-through */
886         case 0:
887             /* Canonicalized version of NetName parameter */
888             InfoStruct->ShareInfo0->shi0_netname = wcsdup(NetName);
889             break;
890         case 501:
891         case 502:
892         case 503:
893         case 1004:
894         case 1005:
895         case 1006:
896         default:
897             status = ERROR_INVALID_LEVEL;
898         }
899         cm_ReleaseSCache(scp);
900     } else {
901         /*
902          * The requested object does not exist.
903          * Return the correct NERR or Win32 Error.
904          */
905         smb_MapWin32Error(code, &status);
906         switch (status) {
907         case ERROR_FILE_NOT_FOUND:
908         case ERROR_PATH_NOT_FOUND:
909         case ERROR_INVALID_NAME:
910         case ERROR_BAD_NETPATH:
911             status = NERR_NetNameNotFound;
912             break;
913         }
914     }
915     return status;
916 }
917
918 NET_API_STATUS NetrShareSetInfo(
919     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
920     /* [string][in] */ WCHAR *NetName,
921     /* [in] */ DWORD Level,
922     /* [switch_is][in] */ LPSHARE_INFO ShareInfo,
923     /* [unique][out][in] */ DWORD *ParmErr)
924 {
925     osi_Log0(afsd_logp, "NetrShareSetInfo not supported");
926     return ERROR_NOT_SUPPORTED;
927 }
928
929 NET_API_STATUS NetrShareDel(
930     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
931     /* [string][in] */ WCHAR *NetName,
932     /* [in] */ DWORD Reserved)
933 {
934     osi_Log0(afsd_logp, "NetrShareDel not supported");
935     return ERROR_NOT_SUPPORTED;
936 }
937
938 NET_API_STATUS NetrShareDelSticky(
939     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
940     /* [string][in] */ WCHAR *NetName,
941     /* [in] */ DWORD Reserved)
942 {
943     osi_Log0(afsd_logp, "NetrShareDelSticky not supported");
944     return ERROR_NOT_SUPPORTED;
945 }
946
947 NET_API_STATUS NetrShareCheck(
948     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
949     /* [string][in] */ WCHAR *Device,
950     /* [out] */ DWORD *Type)
951 {
952     osi_Log0(afsd_logp, "NetrShareCheck not supported");
953     return ERROR_NOT_SUPPORTED;
954 }
955
956 NET_API_STATUS NetrServerGetInfo(
957     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
958     /* [in] */ DWORD Level,
959     /* [switch_is][out] */ LPSERVER_INFO InfoStruct)
960 {
961     wchar_t *s;
962
963     osi_Log1(afsd_logp, "NetrServerGetInfo level %u", Level);
964     /*
965      * How much space do we need and do we have that much room?
966      * For now, just assume we can return everything in one shot
967      * because the reality is that in this function call we do
968      * not know the max size of the RPC response.
969      */
970     switch (Level) {
971     case 103:
972         InfoStruct->ServerInfo103 = MIDL_user_allocate(sizeof(SERVER_INFO_103));
973         break;
974     case 102:
975         InfoStruct->ServerInfo102 = MIDL_user_allocate(sizeof(SERVER_INFO_102));
976         break;
977     case 101:
978         InfoStruct->ServerInfo101 = MIDL_user_allocate(sizeof(SERVER_INFO_101));
979         break;
980     case 100:
981         InfoStruct->ServerInfo100 = MIDL_user_allocate(sizeof(SERVER_INFO_100));
982         break;
983     }
984
985     if (InfoStruct->ServerInfo100 == NULL) {
986         return ERROR_NOT_ENOUGH_MEMORY;
987     }
988
989     /*
990      * Remove any leading slashes since they are not part of the
991      * server name.
992      */
993     for ( s=ServerName; *s == '\\' || *s == '/'; s++);
994
995     switch (Level) {
996     case 103:
997         InfoStruct->ServerInfo103->sv103_capabilities = 0;
998         /* fall-through */
999     case 102:
1000         InfoStruct->ServerInfo102->sv102_users = 0xFFFFFFFF;
1001         InfoStruct->ServerInfo102->sv102_disc = SV_NODISC;
1002         InfoStruct->ServerInfo102->sv102_hidden = SV_HIDDEN;
1003         InfoStruct->ServerInfo102->sv102_announce = 65535;
1004         InfoStruct->ServerInfo102->sv102_anndelta = 0;
1005         InfoStruct->ServerInfo102->sv102_licenses = 0;
1006         InfoStruct->ServerInfo102->sv102_userpath = wcsdup(L"C:\\");
1007         /* fall-through */
1008     case 101:
1009         InfoStruct->ServerInfo101->sv101_version_major = AFSPRODUCT_VERSION_MAJOR;
1010         InfoStruct->ServerInfo101->sv101_version_minor = AFSPRODUCT_VERSION_MINOR;
1011         InfoStruct->ServerInfo101->sv101_type = SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_SERVER_UNIX;
1012         InfoStruct->ServerInfo101->sv101_comment = wcsdup(wAFSVersion);
1013         /* fall-through */
1014     case 100:
1015         InfoStruct->ServerInfo100->sv100_platform_id = SV_PLATFORM_ID_AFS;
1016         /* The Netbios Name */
1017         InfoStruct->ServerInfo100->sv100_name = _wcsupr(wcsdup(s));
1018         return 0;
1019     case 502:
1020     case 503:
1021     case 599:
1022     case 1005:
1023     case 1107:
1024     case 1010:
1025     case 1016:
1026     case 1017:
1027     case 1018:
1028     case 1501:
1029     case 1502:
1030     case 1503:
1031     case 1506:
1032     case 1510:
1033     case 1511:
1034     case 1512:
1035     case 1513:
1036     case 1514:
1037     case 1515:
1038     case 1516:
1039     case 1518:
1040     case 1523:
1041     case 1528:
1042     case 1529:
1043     case 1530:
1044     case 1533:
1045     case 1534:
1046     case 1535:
1047     case 1536:
1048     case 1538:
1049     case 1539:
1050     case 1540:
1051     case 1541:
1052     case 1542:
1053     case 1543:
1054     case 1544:
1055     case 1545:
1056     case 1546:
1057     case 1547:
1058     case 1548:
1059     case 1549:
1060     case 1550:
1061     case 1552:
1062     case 1553:
1063     case 1554:
1064     case 1555:
1065     case 1556:
1066     default:
1067         return ERROR_INVALID_LEVEL;
1068     }
1069     return 0;
1070 }
1071
1072 NET_API_STATUS NetrServerSetInfo(
1073     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1074     /* [in] */ DWORD Level,
1075     /* [switch_is][in] */ LPSERVER_INFO ServerInfo,
1076     /* [unique][out][in] */ DWORD *ParmErr)
1077 {
1078     osi_Log0(afsd_logp, "NetrServerSetInfo not supported");
1079     return ERROR_NOT_SUPPORTED;
1080 }
1081
1082 NET_API_STATUS NetrServerDiskEnum(
1083     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1084     /* [in] */ DWORD Level,
1085     /* [out][in] */ DISK_ENUM_CONTAINER *DiskInfoStruct,
1086     /* [in] */ DWORD PreferedMaximumLength,
1087     /* [out] */ DWORD *TotalEntries,
1088     /* [unique][out][in] */ DWORD *ResumeHandle)
1089 {
1090     osi_Log0(afsd_logp, "NetrServerDiskEnum not supported");
1091     return ERROR_NOT_SUPPORTED;
1092 }
1093
1094 NET_API_STATUS NetrServerStatisticsGet(
1095     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1096     /* [unique][string][in] */ WCHAR *Service,
1097     /* [in] */ DWORD Level,
1098     /* [in] */ DWORD Options,
1099     /* [out] */ LPSTAT_SERVER_0 *InfoStruct)
1100 {
1101     osi_Log0(afsd_logp, "NetrServerStatisticsGet not supported");
1102     return ERROR_NOT_SUPPORTED;
1103 }
1104
1105 NET_API_STATUS NetrServerTransportAdd(
1106     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1107     /* [in] */ DWORD Level,
1108     /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer)
1109 {
1110     osi_Log0(afsd_logp, "NetrServerTransportAdd not supported");
1111     return ERROR_NOT_SUPPORTED;
1112 }
1113
1114 NET_API_STATUS NetrServerTransportEnum(
1115     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1116     /* [out][in] */ LPSERVER_XPORT_ENUM_STRUCT InfoStruct,
1117     /* [in] */ DWORD PreferedMaximumLength,
1118     /* [out] */ DWORD *TotalEntries,
1119     /* [unique][out][in] */ DWORD *ResumeHandle)
1120 {
1121     osi_Log0(afsd_logp, "NetrServerTransportEnum not supported");
1122     return ERROR_NOT_SUPPORTED;
1123 }
1124
1125 NET_API_STATUS NetrServerTransportDel(
1126     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1127     /* [in] */ DWORD Level,
1128     /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer)
1129 {
1130     osi_Log0(afsd_logp, "NetrServerTransportDel not supported");
1131     return ERROR_NOT_SUPPORTED;
1132 }
1133
1134 NET_API_STATUS NetrRemoteTOD(
1135     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1136     /* [out] */ LPTIME_OF_DAY_INFO *BufferPtr)
1137 {
1138     osi_Log0(afsd_logp, "NetrRemoteTOD not supported");
1139     return ERROR_NOT_SUPPORTED;
1140 }
1141
1142 NET_API_STATUS NetprPathType(
1143     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1144     /* [string][in] */ WCHAR *PathName,
1145     /* [out] */ DWORD *PathType,
1146     /* [in] */ DWORD Flags)
1147 {
1148     osi_Log0(afsd_logp, "NetprPathType not supported");
1149     return ERROR_NOT_SUPPORTED;
1150 }
1151
1152 NET_API_STATUS NetprPathCanonicalize(
1153     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1154     /* [string][in] */ WCHAR *PathName,
1155     /* [size_is][out] */ unsigned char *Outbuf,
1156     /* [range][in] */ DWORD OutbufLen,
1157     /* [string][in] */ WCHAR *Prefix,
1158     /* [out][in] */ DWORD *PathType,
1159     /* [in] */ DWORD Flags)
1160 {
1161     osi_Log0(afsd_logp, "NetprPathCanonicalize not supported");
1162     return ERROR_NOT_SUPPORTED;
1163 }
1164
1165 long NetprPathCompare(
1166     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1167     /* [string][in] */ WCHAR *PathName1,
1168     /* [string][in] */ WCHAR *PathName2,
1169     /* [in] */ DWORD PathType,
1170     /* [in] */ DWORD Flags)
1171 {
1172     osi_Log0(afsd_logp, "NetprPathCompare not supported");
1173     return ERROR_NOT_SUPPORTED;
1174 }
1175
1176 NET_API_STATUS NetprNameValidate(
1177     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1178     /* [string][in] */ WCHAR *Name,
1179     /* [in] */ DWORD NameType,
1180     /* [in] */ DWORD Flags)
1181 {
1182     osi_Log0(afsd_logp, "NetprNameValidate not supported");
1183     return ERROR_NOT_SUPPORTED;
1184 }
1185
1186 NET_API_STATUS NetprNameCanonicalize(
1187     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1188     /* [string][in] */ WCHAR *Name,
1189     /* [size_is][out] */ WCHAR *Outbuf,
1190     /* [range][in] */ DWORD OutbufLen,
1191     /* [in] */ DWORD NameType,
1192     /* [in] */ DWORD Flags)
1193 {
1194     osi_Log0(afsd_logp, "NetprNameCanonicalize not supported");
1195     return ERROR_NOT_SUPPORTED;
1196 }
1197
1198 long NetprNameCompare(
1199     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1200     /* [string][in] */ WCHAR *Name1,
1201     /* [string][in] */ WCHAR *Name2,
1202     /* [in] */ DWORD NameType,
1203     /* [in] */ DWORD Flags)
1204 {
1205     osi_Log0(afsd_logp, "NetprNameCompare not supported");
1206     return ERROR_NOT_SUPPORTED;
1207 }
1208
1209 NET_API_STATUS NetrShareEnumSticky(
1210     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1211     /* [out][in] */ LPSHARE_ENUM_STRUCT InfoStruct,
1212     /* [in] */ DWORD PreferedMaximumLength,
1213     /* [out] */ DWORD *TotalEntries,
1214     /* [unique][out][in] */ DWORD *ResumeHandle)
1215 {
1216     osi_Log0(afsd_logp, "NetrShareEnumSticky not supported");
1217     return ERROR_NOT_SUPPORTED;
1218 }
1219
1220 NET_API_STATUS NetrShareDelStart(
1221     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1222     /* [string][in] */ WCHAR *NetName,
1223     /* [in] */ DWORD Reserved,
1224     /* [out] */ PSHARE_DEL_HANDLE ContextHandle)
1225 {
1226     osi_Log0(afsd_logp, "NetrShareDelStart not supported");
1227     return ERROR_NOT_SUPPORTED;
1228 }
1229
1230 NET_API_STATUS NetrShareDelCommit(
1231     /* [out][in] */ PSHARE_DEL_HANDLE ContextHandle)
1232 {
1233     osi_Log0(afsd_logp, "NetrShareDelCommit not supported");
1234     return ERROR_NOT_SUPPORTED;
1235 }
1236
1237 DWORD NetrpGetFileSecurity(
1238     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1239     /* [unique][string][in] */ WCHAR *ShareName,
1240     /* [string][in] */ WCHAR *lpFileName,
1241     /* [in] */ SECURITY_INFORMATION RequestedInformation,
1242     /* [out] */ PADT_SECURITY_DESCRIPTOR *SecurityDescriptor)
1243 {
1244     osi_Log0(afsd_logp, "NetprGetFileSecurity not supported");
1245     return ERROR_NOT_SUPPORTED;
1246 }
1247
1248 DWORD NetrpSetFileSecurity(
1249     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1250     /* [unique][string][in] */ WCHAR *ShareName,
1251     /* [string][in] */ WCHAR *lpFileName,
1252     /* [in] */ SECURITY_INFORMATION SecurityInformation,
1253     /* [in] */ PADT_SECURITY_DESCRIPTOR SecurityDescriptor)
1254 {
1255     osi_Log0(afsd_logp, "NetprSetFileSecurity not supported");
1256     return ERROR_NOT_SUPPORTED;
1257 }
1258
1259 NET_API_STATUS NetrServerTransportAddEx(
1260     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1261     /* [in] */ DWORD Level,
1262     /* [switch_is][in] */ LPTRANSPORT_INFO Buffer)
1263 {
1264     osi_Log0(afsd_logp, "NetrServerTransportAddEx not supported");
1265     return ERROR_NOT_SUPPORTED;
1266 }
1267
1268 NET_API_STATUS NetrDfsGetVersion(
1269     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1270     /* [out] */ DWORD *Version)
1271 {
1272     osi_Log0(afsd_logp, "NetrDfsGetVersion not supported");
1273     return ERROR_NOT_SUPPORTED;
1274 }
1275
1276 NET_API_STATUS NetrDfsCreateLocalPartition(
1277     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1278     /* [string][in] */ WCHAR *ShareName,
1279     /* [in] */ GUID *EntryUid,
1280     /* [string][in] */ WCHAR *EntryPrefix,
1281     /* [string][in] */ WCHAR *ShortName,
1282     /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo,
1283     /* [in] */ int Force)
1284 {
1285     osi_Log0(afsd_logp, "NetrDfsCreateLocalPartition not supported");
1286     return ERROR_NOT_SUPPORTED;
1287 }
1288
1289 NET_API_STATUS NetrDfsDeleteLocalPartition(
1290     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1291     /* [in] */ GUID *Uid,
1292     /* [string][in] */ WCHAR *Prefix)
1293 {
1294     osi_Log0(afsd_logp, "NetrDfsDeleteLocalPartition not supported");
1295     return ERROR_NOT_SUPPORTED;
1296 }
1297
1298 NET_API_STATUS NetrDfsSetLocalVolumeState(
1299     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1300     /* [in] */ GUID *Uid,
1301     /* [string][in] */ WCHAR *Prefix,
1302     /* [in] */ unsigned long State)
1303 {
1304     osi_Log0(afsd_logp, "NetrDfsSetLocalVolumeState not supported");
1305     return ERROR_NOT_SUPPORTED;
1306 }
1307
1308 NET_API_STATUS NetrDfsCreateExitPoint(
1309     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1310     /* [in] */ GUID *Uid,
1311     /* [string][in] */ WCHAR *Prefix,
1312     /* [in] */ unsigned long Type,
1313     /* [range][in] */ DWORD ShortPrefixLen,
1314     /* [size_is][string][out] */ WCHAR *ShortPrefix)
1315 {
1316     osi_Log0(afsd_logp, "NetrDfsCreateExitPoint not supported");
1317     return ERROR_NOT_SUPPORTED;
1318 }
1319
1320 NET_API_STATUS NetrDfsDeleteExitPoint(
1321     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1322     /* [in] */ GUID *Uid,
1323     /* [string][in] */ WCHAR *Prefix,
1324     /* [in] */ unsigned long Type)
1325 {
1326     osi_Log0(afsd_logp, "NetrDfsDeleteExitPoint not supported");
1327     return ERROR_NOT_SUPPORTED;
1328 }
1329
1330 NET_API_STATUS NetrDfsModifyPrefix(
1331     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1332     /* [in] */ GUID *Uid,
1333     /* [string][in] */ WCHAR *Prefix)
1334 {
1335     osi_Log0(afsd_logp, "NetrDfsModifyPrefix not supported");
1336     return ERROR_NOT_SUPPORTED;
1337 }
1338
1339 NET_API_STATUS NetrDfsFixLocalVolume(
1340     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1341     /* [string][in] */ WCHAR *VolumeName,
1342     /* [in] */ unsigned long EntryType,
1343     /* [in] */ unsigned long ServiceType,
1344     /* [string][in] */ WCHAR *StgId,
1345     /* [in] */ GUID *EntryUid,
1346     /* [string][in] */ WCHAR *EntryPrefix,
1347     /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo,
1348     /* [in] */ unsigned long CreateDisposition)
1349 {
1350     osi_Log0(afsd_logp, "NetrDfsFixLocalVolume not supported");
1351     return ERROR_NOT_SUPPORTED;
1352 }
1353
1354 NET_API_STATUS NetrDfsManagerReportSiteInfo(
1355     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1356     /* [unique][out][in] */ LPDFS_SITELIST_INFO *ppSiteInfo)
1357 {
1358     osi_Log0(afsd_logp, "NetrDfsManagerReportSiteInfo not supported");
1359     return ERROR_NOT_SUPPORTED;
1360 }
1361
1362 NET_API_STATUS NetrServerTransportDelEx(
1363     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1364     /* [in] */ DWORD Level,
1365     /* [switch_is][in] */ LPTRANSPORT_INFO Buffer)
1366 {
1367     osi_Log0(afsd_logp, "NetrServerTransportDelEx not supported");
1368     return ERROR_NOT_SUPPORTED;
1369 }
1370
1371 NET_API_STATUS NetrServerAliasAdd(
1372     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1373     /* [in] */ DWORD Level,
1374     /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct)
1375 {
1376     osi_Log0(afsd_logp, "NetrServerAliasAdd not supported");
1377     return ERROR_NOT_SUPPORTED;
1378 }
1379
1380 NET_API_STATUS NetrServerAliasEnum(
1381     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1382     /* [out][in] */ LPSERVER_ALIAS_ENUM_STRUCT InfoStruct,
1383     /* [in] */ DWORD PreferedMaximumLength,
1384     /* [out] */ LPDWORD TotalEntries,
1385     /* [unique][out][in] */ LPDWORD ResumeHandle)
1386 {
1387     osi_Log0(afsd_logp, "NetrServerAliasEnum not supported");
1388     return ERROR_NOT_SUPPORTED;
1389 }
1390
1391 NET_API_STATUS NetrServerAliasDel(
1392     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1393     /* [in] */ DWORD Level,
1394     /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct)
1395 {
1396     osi_Log0(afsd_logp, "NetrServerAliasDel not supported");
1397     return ERROR_NOT_SUPPORTED;
1398 }
1399
1400 NET_API_STATUS NetrShareDelEx(
1401     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1402     /* [in] */ DWORD Level,
1403     /* [switch_is][in] */ LPSHARE_INFO ShareInfo)
1404 {
1405     osi_Log0(afsd_logp, "NetrShareDelEx not supported");
1406     return ERROR_NOT_SUPPORTED;
1407 }
1408
1409
1410 void __RPC_USER SHARE_DEL_HANDLE_rundown( SHARE_DEL_HANDLE h)
1411 {
1412 }
1413
1414 /* [nocode] */ void Opnum0NotUsedOnWire(
1415     /* [in] */ handle_t IDL_handle)
1416 {
1417 }
1418
1419 /* [nocode] */ void Opnum1NotUsedOnWire(
1420     /* [in] */ handle_t IDL_handle)
1421 {
1422 }
1423
1424 /* [nocode] */ void Opnum2NotUsedOnWire(
1425     /* [in] */ handle_t IDL_handle)
1426 {
1427 }
1428
1429 #if 0
1430 /* [nocode] */ void Opnum3NotUsedOnWire(
1431     /* [in] */ handle_t IDL_handle)
1432 {
1433 }
1434
1435 /* [nocode] */ void Opnum4NotUsedOnWire(
1436     /* [in] */ handle_t IDL_handle)
1437 {
1438 }
1439 #endif
1440
1441 /* [nocode] */ void Opnum5NotUsedOnWire(
1442     /* [in] */ handle_t IDL_handle)
1443 {
1444 }
1445
1446 /* [nocode] */ void Opnum6NotUsedOnWire(
1447     /* [in] */ handle_t IDL_handle)
1448 {
1449 }
1450
1451 /* [nocode] */ void Opnum7NotUsedOnWire(
1452     /* [in] */ handle_t IDL_handle)
1453 {
1454 }
1455
1456 /* [nocode] */ void Opnum29NotUsedOnWire(
1457     /* [in] */ handle_t IDL_handle)
1458 {
1459 }
1460
1461 /* [nocode] */ void Opnum42NotUsedOnWire(
1462     /* [in] */ handle_t IDL_handle)
1463 {
1464 }
1465
1466 /* [nocode] */ void Opnum47NotUsedOnWire(
1467     /* [in] */ handle_t IDL_handle)
1468 {
1469 }
1470