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