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