Windows: Do not reference cm_data.rootSCachep directly
[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;
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     dscp = cm_RootSCachep(userp, &req);
474
475     RPC_SRVSVC_ShareEnumAgeCheck();
476
477     /* We only support one server name so ignore 'ServerName'. */
478
479     /* Test for unsupported level early */
480     switch (InfoStruct->Level) {
481     case 2:
482     case 1:
483     case 0:
484         break;
485     default:
486         return ERROR_INVALID_LEVEL;
487     }
488
489     if (ResumeHandle && *ResumeHandle == 0xFFFFFFFF) {
490         /* No More Entries */
491         InfoStruct->ShareInfo.Level0->EntriesRead = 0;
492         return ERROR_NO_MORE_FILES;
493     }
494
495     /* get the directory size */
496     cm_HoldSCache(dscp);
497     lock_ObtainWrite(&dscp->rw);
498     code = cm_SyncOp(dscp, NULL, userp, &req, PRSFS_LOOKUP,
499                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
500     if (code) {
501         lock_ReleaseWrite(&dscp->rw);
502         cm_ReleaseSCache(dscp);
503         osi_Log1(afsd_logp, "NetShareEnum cm_SyncOp failure code=0x%x", code);
504         return ERROR_BUSY;
505     }
506
507     cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
508     lock_ReleaseWrite(&dscp->rw);
509
510     if (dscp->fileType != CM_SCACHETYPE_DIRECTORY) {
511         cm_ReleaseSCache(dscp);
512         osi_Log1(afsd_logp, "NetShareEnum Not a Directory dscp=0x%p", dscp);
513         return ERROR_DIRECTORY;
514     }
515
516     /*
517      * If there is no enumeration handle, then this is a new query
518      * and we must perform an enumeration for the specified object
519      */
520     if (ResumeHandle == NULL || *ResumeHandle == 0) {
521         cm_dirOp_t    dirop;
522
523         code = cm_BeginDirOp(dscp, userp, &req, CM_DIRLOCK_READ,
524                              CM_DIROP_FLAG_NONE, &dirop);
525         if (code == 0) {
526             code = cm_BPlusDirEnumerate(dscp, userp, &req, TRUE, NULL, TRUE, &enump);
527             if (code) {
528                 osi_Log1(afsd_logp, "NetShareEnum cm_BPlusDirEnumerate failure code=0x%x",
529                           code);
530             }
531             cm_EndDirOp(&dirop);
532         } else {
533             osi_Log1(afsd_logp, "NetShareEnum cm_BeginDirOp failure code=0x%x",
534                       code);
535         }
536         old_enum = 0;
537     } else {
538         enump = RPC_SRVSVC_ShareEnumFind(*ResumeHandle);
539         old_enum = 1;
540     }
541
542     if (enump == NULL) {
543         cm_ReleaseSCache(dscp);
544         osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present");
545         *TotalEntries = 0;
546         return (code ? ERROR_BUSY : ERROR_SUCCESS);
547     }
548
549     /*
550      * Do not exceed PreferredMaximumLength in any response.
551      * 0xFFFFFFFF means no limit.
552      *
553      * *TotalEntries is a hint of the total entries in the
554      * enumeration.  It does not have to be exact.  It is
555      * the same for each response in an enum.
556      *
557      * If *ResumeHandle == 0, this is an initial call
558      *
559      * The algorithm will be to enumerate the list of share
560      * names based upon the contents of the root.afs root
561      * directory.  We will ignore SMB submount names.
562      * The enumeration will be valid for five minutes.  If
563      * the enumeration is not destroyed within that time period
564      * it will be automatically garbage collected.
565      */
566
567     /*
568      * How much space do we need and do we have that much room?
569      *
570      * If a preferred maximum length is specified, then we must
571      * manage the number of bytes we return in order to restrict
572      * it to a value smaller than then the preferred.  This includes
573      * not only the InfoStruct but also the allocated SHARE_INFO
574      * buffer and the various C strings.  We are not permitted to
575      * send incomplete values so we will send a value that is close.
576      */
577     if (PreferedMaximumLength != 0xFFFFFFFF) {
578         space_limited = 1;
579         space_available =  PreferedMaximumLength;
580     }
581
582     switch (InfoStruct->Level) {
583     case 2:
584         if (space_limited)
585             space_available -= sizeof(InfoStruct->ShareInfo.Level2);
586         InfoStruct->ShareInfo.Level2->Buffer = calloc((enump->count - enump->next), sizeof(SHARE_INFO_2));
587         break;
588     case 1:
589         if (space_limited)
590             space_available -= sizeof(InfoStruct->ShareInfo.Level1);
591         InfoStruct->ShareInfo.Level1->Buffer = calloc((enump->count - enump->next), sizeof(SHARE_INFO_1));
592         break;
593     case 0:
594         if (space_limited)
595             space_available -= sizeof(InfoStruct->ShareInfo.Level0);
596         InfoStruct->ShareInfo.Level0->Buffer = calloc((enump->count - enump->next), sizeof(SHARE_INFO_0));
597         break;
598     }
599
600     if (InfoStruct->ShareInfo.Level0->Buffer == NULL) {
601         cm_ReleaseSCache(dscp);
602         cm_BPlusDirFreeEnumeration(enump);
603         osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present");
604         return ERROR_NOT_ENOUGH_MEMORY;
605     }
606
607     while (!stopnow) {
608         cm_scache_t *scp;
609
610         if (space_limited)
611             code = cm_BPlusDirPeekNextEnumEntry(enump, &entryp);
612         else
613             code = cm_BPlusDirNextEnumEntry(enump, &entryp);
614         if (code != 0 && code != CM_ERROR_STOPNOW || entryp == NULL)
615             break;
616
617         stopnow = (code == CM_ERROR_STOPNOW);
618
619         if ( !wcscmp(L".", entryp->name) || !wcscmp(L"..", entryp->name) ) {
620             osi_Log0(afsd_logp, "NetShareEnum skipping . or ..");
621             if (space_limited)
622                 cm_BPlusDirNextEnumEntry(enump, &entryp);
623             continue;
624         }
625
626         cm_GetSCache(&entryp->fid, &scp, userp, &req);
627
628         switch (InfoStruct->Level) {
629         case 2:
630             /* for share level security */
631             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_permissions = 0;
632             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_max_uses = -1;
633             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_current_uses = 0;
634             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path =
635                 NetrIntGenerateSharePath(ServerName, &entryp->fid);
636             /* must be the empty string */
637             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_passwd = wcsdup(L"");
638
639             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_type = STYPE_DISKTREE;
640             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark =
641                 NetrIntGenerateShareRemark(scp, &entryp->fid);
642             InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname = wcsdup(entryp->name);
643             break;
644         case 1:
645             InfoStruct->ShareInfo.Level1->Buffer[count].shi1_type = STYPE_DISKTREE;
646             InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark =
647                 NetrIntGenerateShareRemark(scp, &entryp->fid);
648             InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname = wcsdup(entryp->name);
649             break;
650         case 0:
651             InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname = wcsdup(entryp->name);
652         }
653
654         if (scp)
655             cm_ReleaseSCache(scp);
656
657         if (space_limited) {
658             size_t space_used;
659             /*
660              * If space is limited, we need to determine if there is room
661              * for the next entry but always send at least one.
662              */
663             switch (InfoStruct->Level) {
664             case 2:
665                 space_used = sizeof(InfoStruct->ShareInfo.Level2->Buffer[count]) +
666                     (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path) + 1) * sizeof(wchar_t) +
667                     sizeof(wchar_t) +  /* passwd */
668                     (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark) + 1) * sizeof(wchar_t) +
669                     (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname) + 1) * sizeof(wchar_t);
670                 break;
671             case 1:
672                 space_used = sizeof(InfoStruct->ShareInfo.Level1->Buffer[count]) +
673                     (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark) + 1) * sizeof(wchar_t) +
674                     (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname) + 1) * sizeof(wchar_t);
675                 break;
676             case 0:
677                 space_used = sizeof(InfoStruct->ShareInfo.Level0->Buffer[count]) +
678                     (wcslen(InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname) + 1) * sizeof(wchar_t);
679                 break;
680             }
681
682             if (!first_entry && space_used > space_available)
683                 break;
684
685             /* Now consume the entry */
686             cm_BPlusDirNextEnumEntry(enump, &entryp);
687             space_available -= space_used;
688         }
689         count++;
690         first_entry = 0;
691     }
692     InfoStruct->ShareInfo.Level0->EntriesRead = count;
693     *TotalEntries = enump->count;
694     if (dscp)
695         cm_ReleaseSCache(dscp);
696
697     if (code || enump->next == enump->count || ResumeHandle == NULL) {
698         if (old_enum)
699             RPC_SRVSVC_ShareEnumRemove(enump);
700         cm_BPlusDirFreeEnumeration(enump);
701         if (ResumeHandle)
702             *ResumeHandle = 0xFFFFFFFF;
703         return (code || enump->next == enump->count) ? 0 : ERROR_MORE_DATA;
704     } else {
705         *ResumeHandle = RPC_SRVSVC_ShareEnumSave(enump);
706         return ERROR_MORE_DATA;
707     }
708 }
709
710 NET_API_STATUS NetrShareGetInfo(
711     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
712     /* [string][in] */ WCHAR *NetName,
713     /* [in] */ DWORD Level,
714     /* [switch_is][out] */ LPSHARE_INFO InfoStruct)
715 {
716     cm_scache_t * dscp;
717     cm_scache_t * scp = NULL;
718     cm_user_t *userp = MSRPC_GetCmUser();
719     cm_req_t      req;
720     afs_uint32    code = 0;
721     NET_API_STATUS status = 0;
722     HKEY parmKey;
723     /* make room for '/@vol:' + mountchar + NULL terminator*/
724     clientchar_t pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH];
725     DWORD  cblen;
726
727     osi_Log1(afsd_logp, "NetrShareGetInfo level %u", Level);
728
729     cm_InitReq(&req);
730
731     dscp = cm_RootSCachep(userp, &req);
732
733     /* Allocate the memory for the response */
734     switch (Level) {
735     case 2:
736         InfoStruct->ShareInfo2 = calloc(1, sizeof(SHARE_INFO_2));
737         break;
738     case 1:
739         InfoStruct->ShareInfo1 = calloc(1, sizeof(SHARE_INFO_1));
740         break;
741     case 0:
742         InfoStruct->ShareInfo0 = calloc(1, sizeof(SHARE_INFO_0));
743         break;
744     }
745
746     if (InfoStruct->ShareInfo0 == NULL) {
747         return ERROR_NOT_ENOUGH_MEMORY;
748     }
749
750     /*
751      * NetName will be:
752      *  1.a an entry in the root.afs volume root directory
753      *  1.b an entry in the Freelance volume root directory
754      *  2. A volume reference: <cell><type><volume>
755      *  3. an SMB Submount name
756      *  4. a cell name that we do not yet have an entry
757      *     for in the Freelance volume root directory
758      */
759
760     /*
761      * To obtain the needed information for the response we
762      * need to obtain the cm_scache_t entry.  First check to
763      * see if the NetName is a volume reference, then check
764      * if the NetName is an entry in the root volume root
765      * directory, finally we can check the SMB Submounts.
766      * Volume references and SMB submounts are not advertised
767      * as part of the Share enumerations but we should provide
768      * Share info for them nevertheless.  Same for the secret
769      * "all" share.
770      */
771
772     /* Check for volume references
773      *
774      * They look like <cell>{%,#}<volume>
775      */
776     if (cm_ClientStrChr(NetName, '%') != NULL ||
777         cm_ClientStrChr(NetName, '#') != NULL)
778     {
779         osi_Log1(afsd_logp, "NetrShareGetInfo found volume reference [%S]",
780                  osi_LogSaveClientString(afsd_logp, NetName));
781
782         cm_ClientStrPrintfN(pathstr, lengthof(pathstr),
783                             _C(CM_PREFIX_VOL) _C("%s"), NetName);
784         code = cm_Lookup(dscp, pathstr, 0, userp, &req, &scp);
785     } else if (cm_ClientStrCmpI(NetName, L"ALL") == 0) {
786         DWORD allSubmount = 1;
787
788         /* if allSubmounts == 0, only return the //mountRoot/all share
789          * if in fact it has been been created in the subMounts table.
790          * This is to allow sites that want to restrict access to the
791          * world to do so.
792          */
793         code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
794                              0, KEY_QUERY_VALUE, &parmKey);
795         if (code == ERROR_SUCCESS) {
796             cblen = sizeof(allSubmount);
797             code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL,
798                                     (BYTE *) &allSubmount, &cblen);
799             if (code != ERROR_SUCCESS) {
800                 allSubmount = 1;
801             }
802             RegCloseKey (parmKey);
803         }
804
805         if (allSubmount) {
806             scp = dscp;
807             cm_HoldSCache(scp);
808         }
809     } else {
810         /*
811          * Could be a Submount, a directory entry, or a cell name we
812          * have yet to create an entry for.
813          */
814
815         /* Try a directory entry first */
816         code = cm_Lookup(dscp, NetName, CM_FLAG_NOMOUNTCHASE,
817                           userp, &req, &scp);
818         if (code && code != CM_ERROR_NOACCESS)
819             code = cm_Lookup(dscp, NetName, CM_FLAG_CASEFOLD | CM_FLAG_NOMOUNTCHASE,
820                               userp, &req, &scp);
821
822         if (scp == NULL && code != CM_ERROR_NOACCESS) {  /* Try a submount */
823             code = RegOpenKeyExW(HKEY_LOCAL_MACHINE,  L"Software\\OpenAFS\\Client\\Submounts",
824                                   0, KEY_QUERY_VALUE, &parmKey);
825             if (code == ERROR_SUCCESS) {
826                 cblen = sizeof(pathstr);
827                 code = RegQueryValueExW(parmKey, NetName, NULL, NULL,
828                                          (BYTE *) pathstr, &cblen);
829                 if (code != ERROR_SUCCESS)
830                     cblen = 0;
831                 RegCloseKey (parmKey);
832             } else {
833                 cblen = 0;
834             }
835
836             if (cblen) {
837                 code = cm_NameI(dscp, pathstr, CM_FLAG_FOLLOW, userp, NULL, &req, &scp);
838                 if (code && code != CM_ERROR_NOACCESS)
839                     code = cm_NameI(dscp, pathstr, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
840                                       userp, NULL, &req, &scp);
841             }
842         }
843     }
844
845     if (scp) {
846         switch (Level) {
847         case 2:
848             /* for share level security */
849             InfoStruct->ShareInfo2->shi2_permissions = 0;
850             InfoStruct->ShareInfo2->shi2_max_uses = -1;
851             InfoStruct->ShareInfo2->shi2_current_uses = 0;
852             InfoStruct->ShareInfo2->shi2_path =
853                 NetrIntGenerateSharePath(ServerName, &scp->fid);
854             /* must be the empty string */
855             InfoStruct->ShareInfo2->shi2_passwd = wcsdup(L"");
856             /* fall-through */
857         case 1:
858             InfoStruct->ShareInfo1->shi1_type = STYPE_DISKTREE;
859             InfoStruct->ShareInfo1->shi1_remark =
860                 NetrIntGenerateShareRemark(scp, &scp->fid);
861             /* fall-through */
862         case 0:
863             /* Canonicalized version of NetName parameter */
864             InfoStruct->ShareInfo0->shi0_netname = wcsdup(NetName);
865             break;
866         case 501:
867         case 502:
868         case 503:
869         case 1004:
870         case 1005:
871         case 1006:
872         default:
873             status = ERROR_INVALID_LEVEL;
874         }
875         cm_ReleaseSCache(scp);
876     } else {
877         /*
878          * The requested object does not exist.
879          * Return the correct NERR or Win32 Error.
880          */
881         smb_MapWin32Error(code, &status);
882         switch (status) {
883         case ERROR_FILE_NOT_FOUND:
884         case ERROR_PATH_NOT_FOUND:
885         case ERROR_INVALID_NAME:
886         case ERROR_BAD_NETPATH:
887             status = NERR_NetNameNotFound;
888             break;
889         }
890     }
891     return status;
892 }
893
894 NET_API_STATUS NetrShareSetInfo(
895     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
896     /* [string][in] */ WCHAR *NetName,
897     /* [in] */ DWORD Level,
898     /* [switch_is][in] */ LPSHARE_INFO ShareInfo,
899     /* [unique][out][in] */ DWORD *ParmErr)
900 {
901     osi_Log0(afsd_logp, "NetrShareSetInfo not supported");
902     return ERROR_NOT_SUPPORTED;
903 }
904
905 NET_API_STATUS NetrShareDel(
906     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
907     /* [string][in] */ WCHAR *NetName,
908     /* [in] */ DWORD Reserved)
909 {
910     osi_Log0(afsd_logp, "NetrShareDel not supported");
911     return ERROR_NOT_SUPPORTED;
912 }
913
914 NET_API_STATUS NetrShareDelSticky(
915     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
916     /* [string][in] */ WCHAR *NetName,
917     /* [in] */ DWORD Reserved)
918 {
919     osi_Log0(afsd_logp, "NetrShareDelSticky not supported");
920     return ERROR_NOT_SUPPORTED;
921 }
922
923 NET_API_STATUS NetrShareCheck(
924     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
925     /* [string][in] */ WCHAR *Device,
926     /* [out] */ DWORD *Type)
927 {
928     osi_Log0(afsd_logp, "NetrShareCheck not supported");
929     return ERROR_NOT_SUPPORTED;
930 }
931
932 NET_API_STATUS NetrServerGetInfo(
933     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
934     /* [in] */ DWORD Level,
935     /* [switch_is][out] */ LPSERVER_INFO InfoStruct)
936 {
937     wchar_t *s;
938
939     osi_Log1(afsd_logp, "NetrServerGetInfo level %u", Level);
940     /*
941      * How much space do we need and do we have that much room?
942      * For now, just assume we can return everything in one shot
943      * because the reality is that in this function call we do
944      * not know the max size of the RPC response.
945      */
946     switch (Level) {
947     case 103:
948         InfoStruct->ServerInfo103 = calloc(1, sizeof(SERVER_INFO_103));
949         break;
950     case 102:
951         InfoStruct->ServerInfo102 = calloc(1, sizeof(SERVER_INFO_102));
952         break;
953     case 101:
954         InfoStruct->ServerInfo101 = calloc(1, sizeof(SERVER_INFO_101));
955         break;
956     case 100:
957         InfoStruct->ServerInfo100 = calloc(1, sizeof(SERVER_INFO_100));
958         break;
959     }
960
961     if (InfoStruct->ServerInfo100 == NULL) {
962         return ERROR_NOT_ENOUGH_MEMORY;
963     }
964
965     /*
966      * Remove any leading slashes since they are not part of the
967      * server name.
968      */
969     for ( s=ServerName; *s == '\\' || *s == '/'; s++);
970
971     switch (Level) {
972     case 103:
973         InfoStruct->ServerInfo103->sv103_capabilities = 0;
974         /* fall-through */
975     case 102:
976         InfoStruct->ServerInfo102->sv102_users = 0xFFFFFFFF;
977         InfoStruct->ServerInfo102->sv102_disc = SV_NODISC;
978         InfoStruct->ServerInfo102->sv102_hidden = SV_HIDDEN;
979         InfoStruct->ServerInfo102->sv102_announce = 65535;
980         InfoStruct->ServerInfo102->sv102_anndelta = 0;
981         InfoStruct->ServerInfo102->sv102_licenses = 0;
982         InfoStruct->ServerInfo102->sv102_userpath = wcsdup(L"C:\\");
983         /* fall-through */
984     case 101:
985         InfoStruct->ServerInfo101->sv101_version_major = AFSPRODUCT_VERSION_MAJOR;
986         InfoStruct->ServerInfo101->sv101_version_minor = AFSPRODUCT_VERSION_MINOR;
987         InfoStruct->ServerInfo101->sv101_type = SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_SERVER_UNIX;
988         InfoStruct->ServerInfo101->sv101_comment = wcsdup(wAFSVersion);
989         /* fall-through */
990     case 100:
991         InfoStruct->ServerInfo100->sv100_platform_id = SV_PLATFORM_ID_AFS;
992         /* The Netbios Name */
993         InfoStruct->ServerInfo100->sv100_name = _wcsupr(wcsdup(s));
994         return 0;
995     case 502:
996     case 503:
997     case 599:
998     case 1005:
999     case 1107:
1000     case 1010:
1001     case 1016:
1002     case 1017:
1003     case 1018:
1004     case 1501:
1005     case 1502:
1006     case 1503:
1007     case 1506:
1008     case 1510:
1009     case 1511:
1010     case 1512:
1011     case 1513:
1012     case 1514:
1013     case 1515:
1014     case 1516:
1015     case 1518:
1016     case 1523:
1017     case 1528:
1018     case 1529:
1019     case 1530:
1020     case 1533:
1021     case 1534:
1022     case 1535:
1023     case 1536:
1024     case 1538:
1025     case 1539:
1026     case 1540:
1027     case 1541:
1028     case 1542:
1029     case 1543:
1030     case 1544:
1031     case 1545:
1032     case 1546:
1033     case 1547:
1034     case 1548:
1035     case 1549:
1036     case 1550:
1037     case 1552:
1038     case 1553:
1039     case 1554:
1040     case 1555:
1041     case 1556:
1042     default:
1043         return ERROR_INVALID_LEVEL;
1044     }
1045     return 0;
1046 }
1047
1048 NET_API_STATUS NetrServerSetInfo(
1049     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1050     /* [in] */ DWORD Level,
1051     /* [switch_is][in] */ LPSERVER_INFO ServerInfo,
1052     /* [unique][out][in] */ DWORD *ParmErr)
1053 {
1054     osi_Log0(afsd_logp, "NetrServerSetInfo not supported");
1055     return ERROR_NOT_SUPPORTED;
1056 }
1057
1058 NET_API_STATUS NetrServerDiskEnum(
1059     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1060     /* [in] */ DWORD Level,
1061     /* [out][in] */ DISK_ENUM_CONTAINER *DiskInfoStruct,
1062     /* [in] */ DWORD PreferedMaximumLength,
1063     /* [out] */ DWORD *TotalEntries,
1064     /* [unique][out][in] */ DWORD *ResumeHandle)
1065 {
1066     osi_Log0(afsd_logp, "NetrServerDiskEnum not supported");
1067     return ERROR_NOT_SUPPORTED;
1068 }
1069
1070 NET_API_STATUS NetrServerStatisticsGet(
1071     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1072     /* [unique][string][in] */ WCHAR *Service,
1073     /* [in] */ DWORD Level,
1074     /* [in] */ DWORD Options,
1075     /* [out] */ LPSTAT_SERVER_0 *InfoStruct)
1076 {
1077     osi_Log0(afsd_logp, "NetrServerStatisticsGet not supported");
1078     return ERROR_NOT_SUPPORTED;
1079 }
1080
1081 NET_API_STATUS NetrServerTransportAdd(
1082     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1083     /* [in] */ DWORD Level,
1084     /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer)
1085 {
1086     osi_Log0(afsd_logp, "NetrServerTransportAdd not supported");
1087     return ERROR_NOT_SUPPORTED;
1088 }
1089
1090 NET_API_STATUS NetrServerTransportEnum(
1091     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1092     /* [out][in] */ LPSERVER_XPORT_ENUM_STRUCT InfoStruct,
1093     /* [in] */ DWORD PreferedMaximumLength,
1094     /* [out] */ DWORD *TotalEntries,
1095     /* [unique][out][in] */ DWORD *ResumeHandle)
1096 {
1097     osi_Log0(afsd_logp, "NetrServerTransportEnum not supported");
1098     return ERROR_NOT_SUPPORTED;
1099 }
1100
1101 NET_API_STATUS NetrServerTransportDel(
1102     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1103     /* [in] */ DWORD Level,
1104     /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer)
1105 {
1106     osi_Log0(afsd_logp, "NetrServerTransportDel not supported");
1107     return ERROR_NOT_SUPPORTED;
1108 }
1109
1110 NET_API_STATUS NetrRemoteTOD(
1111     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1112     /* [out] */ LPTIME_OF_DAY_INFO *BufferPtr)
1113 {
1114     osi_Log0(afsd_logp, "NetrRemoteTOD not supported");
1115     return ERROR_NOT_SUPPORTED;
1116 }
1117
1118 NET_API_STATUS NetprPathType(
1119     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1120     /* [string][in] */ WCHAR *PathName,
1121     /* [out] */ DWORD *PathType,
1122     /* [in] */ DWORD Flags)
1123 {
1124     osi_Log0(afsd_logp, "NetprPathType not supported");
1125     return ERROR_NOT_SUPPORTED;
1126 }
1127
1128 NET_API_STATUS NetprPathCanonicalize(
1129     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1130     /* [string][in] */ WCHAR *PathName,
1131     /* [size_is][out] */ unsigned char *Outbuf,
1132     /* [range][in] */ DWORD OutbufLen,
1133     /* [string][in] */ WCHAR *Prefix,
1134     /* [out][in] */ DWORD *PathType,
1135     /* [in] */ DWORD Flags)
1136 {
1137     osi_Log0(afsd_logp, "NetprPathCanonicalize not supported");
1138     return ERROR_NOT_SUPPORTED;
1139 }
1140
1141 long NetprPathCompare(
1142     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1143     /* [string][in] */ WCHAR *PathName1,
1144     /* [string][in] */ WCHAR *PathName2,
1145     /* [in] */ DWORD PathType,
1146     /* [in] */ DWORD Flags)
1147 {
1148     osi_Log0(afsd_logp, "NetprPathCompare not supported");
1149     return ERROR_NOT_SUPPORTED;
1150 }
1151
1152 NET_API_STATUS NetprNameValidate(
1153     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1154     /* [string][in] */ WCHAR *Name,
1155     /* [in] */ DWORD NameType,
1156     /* [in] */ DWORD Flags)
1157 {
1158     osi_Log0(afsd_logp, "NetprNameValidate not supported");
1159     return ERROR_NOT_SUPPORTED;
1160 }
1161
1162 NET_API_STATUS NetprNameCanonicalize(
1163     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1164     /* [string][in] */ WCHAR *Name,
1165     /* [size_is][out] */ WCHAR *Outbuf,
1166     /* [range][in] */ DWORD OutbufLen,
1167     /* [in] */ DWORD NameType,
1168     /* [in] */ DWORD Flags)
1169 {
1170     osi_Log0(afsd_logp, "NetprNameCanonicalize not supported");
1171     return ERROR_NOT_SUPPORTED;
1172 }
1173
1174 long NetprNameCompare(
1175     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1176     /* [string][in] */ WCHAR *Name1,
1177     /* [string][in] */ WCHAR *Name2,
1178     /* [in] */ DWORD NameType,
1179     /* [in] */ DWORD Flags)
1180 {
1181     osi_Log0(afsd_logp, "NetprNameCompare not supported");
1182     return ERROR_NOT_SUPPORTED;
1183 }
1184
1185 NET_API_STATUS NetrShareEnumSticky(
1186     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1187     /* [out][in] */ LPSHARE_ENUM_STRUCT InfoStruct,
1188     /* [in] */ DWORD PreferedMaximumLength,
1189     /* [out] */ DWORD *TotalEntries,
1190     /* [unique][out][in] */ DWORD *ResumeHandle)
1191 {
1192     osi_Log0(afsd_logp, "NetrShareEnumSticky not supported");
1193     return ERROR_NOT_SUPPORTED;
1194 }
1195
1196 NET_API_STATUS NetrShareDelStart(
1197     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1198     /* [string][in] */ WCHAR *NetName,
1199     /* [in] */ DWORD Reserved,
1200     /* [out] */ PSHARE_DEL_HANDLE ContextHandle)
1201 {
1202     osi_Log0(afsd_logp, "NetrShareDelStart not supported");
1203     return ERROR_NOT_SUPPORTED;
1204 }
1205
1206 NET_API_STATUS NetrShareDelCommit(
1207     /* [out][in] */ PSHARE_DEL_HANDLE ContextHandle)
1208 {
1209     osi_Log0(afsd_logp, "NetrShareDelCommit not supported");
1210     return ERROR_NOT_SUPPORTED;
1211 }
1212
1213 DWORD NetrpGetFileSecurity(
1214     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1215     /* [unique][string][in] */ WCHAR *ShareName,
1216     /* [string][in] */ WCHAR *lpFileName,
1217     /* [in] */ SECURITY_INFORMATION RequestedInformation,
1218     /* [out] */ PADT_SECURITY_DESCRIPTOR *SecurityDescriptor)
1219 {
1220     osi_Log0(afsd_logp, "NetprGetFileSecurity not supported");
1221     return ERROR_NOT_SUPPORTED;
1222 }
1223
1224 DWORD NetrpSetFileSecurity(
1225     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1226     /* [unique][string][in] */ WCHAR *ShareName,
1227     /* [string][in] */ WCHAR *lpFileName,
1228     /* [in] */ SECURITY_INFORMATION SecurityInformation,
1229     /* [in] */ PADT_SECURITY_DESCRIPTOR SecurityDescriptor)
1230 {
1231     osi_Log0(afsd_logp, "NetprSetFileSecurity not supported");
1232     return ERROR_NOT_SUPPORTED;
1233 }
1234
1235 NET_API_STATUS NetrServerTransportAddEx(
1236     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1237     /* [in] */ DWORD Level,
1238     /* [switch_is][in] */ LPTRANSPORT_INFO Buffer)
1239 {
1240     osi_Log0(afsd_logp, "NetrServerTransportAddEx not supported");
1241     return ERROR_NOT_SUPPORTED;
1242 }
1243
1244 NET_API_STATUS NetrDfsGetVersion(
1245     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1246     /* [out] */ DWORD *Version)
1247 {
1248     osi_Log0(afsd_logp, "NetrDfsGetVersion not supported");
1249     return ERROR_NOT_SUPPORTED;
1250 }
1251
1252 NET_API_STATUS NetrDfsCreateLocalPartition(
1253     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1254     /* [string][in] */ WCHAR *ShareName,
1255     /* [in] */ GUID *EntryUid,
1256     /* [string][in] */ WCHAR *EntryPrefix,
1257     /* [string][in] */ WCHAR *ShortName,
1258     /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo,
1259     /* [in] */ int Force)
1260 {
1261     osi_Log0(afsd_logp, "NetrDfsCreateLocalPartition not supported");
1262     return ERROR_NOT_SUPPORTED;
1263 }
1264
1265 NET_API_STATUS NetrDfsDeleteLocalPartition(
1266     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1267     /* [in] */ GUID *Uid,
1268     /* [string][in] */ WCHAR *Prefix)
1269 {
1270     osi_Log0(afsd_logp, "NetrDfsDeleteLocalPartition not supported");
1271     return ERROR_NOT_SUPPORTED;
1272 }
1273
1274 NET_API_STATUS NetrDfsSetLocalVolumeState(
1275     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1276     /* [in] */ GUID *Uid,
1277     /* [string][in] */ WCHAR *Prefix,
1278     /* [in] */ unsigned long State)
1279 {
1280     osi_Log0(afsd_logp, "NetrDfsSetLocalVolumeState not supported");
1281     return ERROR_NOT_SUPPORTED;
1282 }
1283
1284 NET_API_STATUS NetrDfsCreateExitPoint(
1285     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1286     /* [in] */ GUID *Uid,
1287     /* [string][in] */ WCHAR *Prefix,
1288     /* [in] */ unsigned long Type,
1289     /* [range][in] */ DWORD ShortPrefixLen,
1290     /* [size_is][string][out] */ WCHAR *ShortPrefix)
1291 {
1292     osi_Log0(afsd_logp, "NetrDfsCreateExitPoint not supported");
1293     return ERROR_NOT_SUPPORTED;
1294 }
1295
1296 NET_API_STATUS NetrDfsDeleteExitPoint(
1297     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1298     /* [in] */ GUID *Uid,
1299     /* [string][in] */ WCHAR *Prefix,
1300     /* [in] */ unsigned long Type)
1301 {
1302     osi_Log0(afsd_logp, "NetrDfsDeleteExitPoint not supported");
1303     return ERROR_NOT_SUPPORTED;
1304 }
1305
1306 NET_API_STATUS NetrDfsModifyPrefix(
1307     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1308     /* [in] */ GUID *Uid,
1309     /* [string][in] */ WCHAR *Prefix)
1310 {
1311     osi_Log0(afsd_logp, "NetrDfsModifyPrefix not supported");
1312     return ERROR_NOT_SUPPORTED;
1313 }
1314
1315 NET_API_STATUS NetrDfsFixLocalVolume(
1316     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1317     /* [string][in] */ WCHAR *VolumeName,
1318     /* [in] */ unsigned long EntryType,
1319     /* [in] */ unsigned long ServiceType,
1320     /* [string][in] */ WCHAR *StgId,
1321     /* [in] */ GUID *EntryUid,
1322     /* [string][in] */ WCHAR *EntryPrefix,
1323     /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo,
1324     /* [in] */ unsigned long CreateDisposition)
1325 {
1326     osi_Log0(afsd_logp, "NetrDfsFixLocalVolume not supported");
1327     return ERROR_NOT_SUPPORTED;
1328 }
1329
1330 NET_API_STATUS NetrDfsManagerReportSiteInfo(
1331     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1332     /* [unique][out][in] */ LPDFS_SITELIST_INFO *ppSiteInfo)
1333 {
1334     osi_Log0(afsd_logp, "NetrDfsManagerReportSiteInfo not supported");
1335     return ERROR_NOT_SUPPORTED;
1336 }
1337
1338 NET_API_STATUS NetrServerTransportDelEx(
1339     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1340     /* [in] */ DWORD Level,
1341     /* [switch_is][in] */ LPTRANSPORT_INFO Buffer)
1342 {
1343     osi_Log0(afsd_logp, "NetrServerTransportDelEx not supported");
1344     return ERROR_NOT_SUPPORTED;
1345 }
1346
1347 NET_API_STATUS NetrServerAliasAdd(
1348     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1349     /* [in] */ DWORD Level,
1350     /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct)
1351 {
1352     osi_Log0(afsd_logp, "NetrServerAliasAdd not supported");
1353     return ERROR_NOT_SUPPORTED;
1354 }
1355
1356 NET_API_STATUS NetrServerAliasEnum(
1357     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1358     /* [out][in] */ LPSERVER_ALIAS_ENUM_STRUCT InfoStruct,
1359     /* [in] */ DWORD PreferedMaximumLength,
1360     /* [out] */ LPDWORD TotalEntries,
1361     /* [unique][out][in] */ LPDWORD ResumeHandle)
1362 {
1363     osi_Log0(afsd_logp, "NetrServerAliasEnum not supported");
1364     return ERROR_NOT_SUPPORTED;
1365 }
1366
1367 NET_API_STATUS NetrServerAliasDel(
1368     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1369     /* [in] */ DWORD Level,
1370     /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct)
1371 {
1372     osi_Log0(afsd_logp, "NetrServerAliasDel not supported");
1373     return ERROR_NOT_SUPPORTED;
1374 }
1375
1376 NET_API_STATUS NetrShareDelEx(
1377     /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1378     /* [in] */ DWORD Level,
1379     /* [switch_is][in] */ LPSHARE_INFO ShareInfo)
1380 {
1381     osi_Log0(afsd_logp, "NetrShareDelEx not supported");
1382     return ERROR_NOT_SUPPORTED;
1383 }
1384
1385
1386 void __RPC_USER SHARE_DEL_HANDLE_rundown( SHARE_DEL_HANDLE h)
1387 {
1388 }
1389
1390 /* [nocode] */ void Opnum0NotUsedOnWire(
1391     /* [in] */ handle_t IDL_handle)
1392 {
1393 }
1394
1395 /* [nocode] */ void Opnum1NotUsedOnWire(
1396     /* [in] */ handle_t IDL_handle)
1397 {
1398 }
1399
1400 /* [nocode] */ void Opnum2NotUsedOnWire(
1401     /* [in] */ handle_t IDL_handle)
1402 {
1403 }
1404
1405 #if 0
1406 /* [nocode] */ void Opnum3NotUsedOnWire(
1407     /* [in] */ handle_t IDL_handle)
1408 {
1409 }
1410
1411 /* [nocode] */ void Opnum4NotUsedOnWire(
1412     /* [in] */ handle_t IDL_handle)
1413 {
1414 }
1415 #endif
1416
1417 /* [nocode] */ void Opnum5NotUsedOnWire(
1418     /* [in] */ handle_t IDL_handle)
1419 {
1420 }
1421
1422 /* [nocode] */ void Opnum6NotUsedOnWire(
1423     /* [in] */ handle_t IDL_handle)
1424 {
1425 }
1426
1427 /* [nocode] */ void Opnum7NotUsedOnWire(
1428     /* [in] */ handle_t IDL_handle)
1429 {
1430 }
1431
1432 /* [nocode] */ void Opnum29NotUsedOnWire(
1433     /* [in] */ handle_t IDL_handle)
1434 {
1435 }
1436
1437 /* [nocode] */ void Opnum42NotUsedOnWire(
1438     /* [in] */ handle_t IDL_handle)
1439 {
1440 }
1441
1442 /* [nocode] */ void Opnum47NotUsedOnWire(
1443     /* [in] */ handle_t IDL_handle)
1444 {
1445 }
1446