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