2 * Copyright (c) 2009 Secure Endpoints Inc.
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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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
31 #include "ms-srvsvc.h"
34 #include <WINNT/afsreg.h>
35 #define AFS_VERSION_STRINGS
36 #include "AFS_component_version_number.h"
38 #pragma warning( disable: 4027 ) /* func w/o formal parameter list */
40 /* Do not pull in lmserver.h */
42 // The platform ID indicates the levels to use for platform-specific
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
52 // Bit-mapped values for svX_type fields. X = 1, 2 or 3.
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 */
88 // Values of svX_hidden field. X = 2 or 3.
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)
101 return ERROR_NOT_SUPPORTED;
104 NET_API_STATUS NetrFileEnum(
105 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
106 /* [unique][string][in] */ WCHAR *BasePath,
107 /* [unique][string][in] */ WCHAR *UserName,
108 /* [out][in] */ PFILE_ENUM_STRUCT InfoStruct,
109 /* [in] */ DWORD PreferedMaximumLength,
110 /* [out] */ DWORD *TotalEntries,
111 /* [unique][out][in] */ DWORD *ResumeHandle)
113 return ERROR_NOT_SUPPORTED;
116 NET_API_STATUS NetrFileGetInfo(
117 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
118 /* [in] */ DWORD FileId,
119 /* [in] */ DWORD Level,
120 /* [switch_is][out] */ LPFILE_INFO InfoStruct)
122 return ERROR_NOT_SUPPORTED;
125 NET_API_STATUS NetrFileClose(
126 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
127 /* [in] */ DWORD FileId)
129 return ERROR_NOT_SUPPORTED;
132 NET_API_STATUS NetrSessionEnum(
133 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
134 /* [unique][string][in] */ WCHAR *ClientName,
135 /* [unique][string][in] */ WCHAR *UserName,
136 /* [out][in] */ PSESSION_ENUM_STRUCT InfoStruct,
137 /* [in] */ DWORD PreferedMaximumLength,
138 /* [out] */ DWORD *TotalEntries,
139 /* [unique][out][in] */ DWORD *ResumeHandle)
141 return ERROR_NOT_SUPPORTED;
144 NET_API_STATUS NetrSessionDel(
145 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
146 /* [unique][string][in] */ WCHAR *ClientName,
147 /* [unique][string][in] */ WCHAR *UserName)
149 return ERROR_NOT_SUPPORTED;
152 NET_API_STATUS NetrShareAdd(
153 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
154 /* [in] */ DWORD Level,
155 /* [switch_is][in] */ LPSHARE_INFO InfoStruct,
156 /* [unique][out][in] */ DWORD *ParmErr)
158 return ERROR_NOT_SUPPORTED;
162 NetrIntGenerateShareRemark(cm_scache_t *scp, cm_fid_t *fidp)
164 wchar_t remark[1536], *s, *wcellname, *wmp;
169 cellp = cm_FindCellByID(fidp->cell, CM_FLAG_NOPROBE);
172 wcellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL);
177 switch (scp->fileType) {
179 hr = StringCchPrintfW( remark,
180 sizeof(remark)/sizeof(remark[0]),
181 L"AFS File (%s:%u.%u.%u)",
184 scp->fid.vnode, scp->fid.unique);
188 s = wcsdup(L"AFS File");
191 hr = StringCchPrintfW( remark,
192 sizeof(remark)/sizeof(remark[0]),
193 L"AFS Directory (%s:%u.%u.%u)",
196 scp->fid.vnode, scp->fid.unique);
200 s = wcsdup(L"AFS Directory");
203 wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL);
204 hr = StringCchPrintfW( remark,
205 sizeof(remark)/sizeof(remark[0]),
206 L"AFS Symlink to %s",
211 s = wcsdup(L"AFS Symlink");
216 b = (strchr(scp->mountPointStringp, ':') != NULL);
217 wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL);
218 hr = StringCchPrintfW( remark,
219 sizeof(remark)/sizeof(remark[0]),
220 L"AFS MountPoint to %s%s%s%s",
228 s = wcsdup(L"AFS MountPoint");
233 wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL);
234 hr = StringCchPrintfW( remark,
235 sizeof(remark)/sizeof(remark[0]),
236 L"AFS Dfslink to %s",
241 s = wcsdup(L"AFS DfsLink");
246 hr = StringCchPrintfW( remark,
247 sizeof(remark)/sizeof(remark[0]),
248 L"AFS Object (%s:%u.%u.%u)",
251 scp->fid.vnode, scp->fid.unique);
255 s = wcsdup(L"AFS Object");
258 if (fidp->vnode & 1) {
259 hr = StringCchPrintfW( remark,
260 sizeof(remark)/sizeof(remark[0]),
261 L"AFS Directory (%s:%u.%u.%u)",
264 fidp->vnode, fidp->unique);
268 s = wcsdup(L"AFS Directory");
270 hr = StringCchPrintfW( remark,
271 sizeof(remark)/sizeof(remark[0]),
272 L"AFS Object (%s:%u.%u.%u)",
275 fidp->vnode, fidp->unique);
279 s = wcsdup(L"AFS Object");
282 if (cellp && wcellname)
288 NetrIntGenerateSharePath(wchar_t *ServerName, cm_fid_t *fidp)
290 wchar_t remark[1536], *s, *wcellname;
294 cellp = cm_FindCellByID(fidp->cell, CM_FLAG_NOPROBE);
297 wcellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL);
301 hr = StringCchPrintfW( remark,
302 sizeof(remark)/sizeof(remark[0]),
303 L"\\%s\\%s\\%u.%u.%u",
304 ServerName, wcellname,
306 fidp->vnode, fidp->unique);
312 if (cellp && wcellname)
317 typedef struct netr_share_enum {
321 cm_direnum_t *direnump;
324 static osi_queue_t * shareEnumQ = NULL;
325 static osi_mutex_t shareEnum_mx;
326 static DWORD shareEnum_next_handle=1;
329 RPC_SRVSVC_Init(void)
331 lock_InitializeMutex(&shareEnum_mx, "NetrShareEnum", 0);
334 srand((unsigned) time( NULL ));
335 shareEnum_next_handle = rand();
337 rand_s(&shareEnum_next_handle);
342 RPC_SRVSVC_Shutdown(void)
344 netr_share_enum_t *enump;
346 lock_ObtainMutex(&shareEnum_mx);
348 enump = (netr_share_enum_t *)shareEnumQ;
349 cm_BPlusDirFreeEnumeration(enump->direnump);
350 osi_QRemove(&shareEnumQ, (osi_queue_t *)enump);
353 lock_FinalizeMutex(&shareEnum_mx);
357 RPC_SRVSVC_ShareEnumAgeCheck(void) {
358 netr_share_enum_t *enump, *enumnp;
361 lock_ObtainMutex(&shareEnum_mx);
363 for (enump = (netr_share_enum_t *)shareEnumQ;
364 enump; enump = enumnp) {
365 enumnp = (netr_share_enum_t *) osi_QNext(&(enump->q));
366 if (now > enump->cleanup_time)
367 osi_QRemove(&shareEnumQ, (osi_queue_t *)enump);
369 lock_ReleaseMutex(&shareEnum_mx);
372 static cm_direnum_t *
373 RPC_SRVSVC_ShareEnumFind(DWORD ResumeHandle) {
374 netr_share_enum_t *enump;
376 lock_ObtainMutex(&shareEnum_mx);
377 for (enump = (netr_share_enum_t *)shareEnumQ;
379 enump = (netr_share_enum_t *) osi_QNext(&enump->q)) {
380 if (ResumeHandle == enump->handle)
383 lock_ReleaseMutex(&shareEnum_mx);
385 return enump ? enump->direnump : NULL;
389 RPC_SRVSVC_ShareEnumSave(cm_direnum_t *direnump) {
390 netr_share_enum_t *enump = (netr_share_enum_t *)malloc(sizeof(netr_share_enum_t));
395 lock_ObtainMutex(&shareEnum_mx);
396 enump->cleanup_time = time(NULL) + 300;
397 enump->handle = shareEnum_next_handle++;
398 if (shareEnum_next_handle == 0xFFFFFFFF)
399 shareEnum_next_handle = 1;
400 enump->direnump = direnump;
401 osi_QAdd(&shareEnumQ, (osi_queue_t *)enump);
402 lock_ReleaseMutex(&shareEnum_mx);
404 return enump->handle;
408 RPC_SRVSVC_ShareEnumRemove(cm_direnum_t *direnump) {
409 netr_share_enum_t *enump;
411 lock_ObtainMutex(&shareEnum_mx);
412 for (enump = (netr_share_enum_t *)shareEnumQ;
414 enump = (netr_share_enum_t *) osi_QNext(&enump->q)) {
415 if (direnump == enump->direnump) {
416 osi_QRemove(&shareEnumQ, (osi_queue_t *)enump);
420 lock_ReleaseMutex(&shareEnum_mx);
423 NET_API_STATUS NetrShareEnum(
424 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
425 /* [out][in] */ LPSHARE_ENUM_STRUCT InfoStruct,
426 /* [in] */ DWORD PreferedMaximumLength,
427 /* [out] */ DWORD *TotalEntries,
428 /* [unique][out][in] */ DWORD *ResumeHandle)
430 cm_direnum_t *enump = NULL;
431 cm_direnum_entry_t * entryp = NULL;
432 cm_scache_t * dscp = cm_data.rootSCachep;
433 cm_user_t *userp = MSRPC_GetCmUser();
436 afs_uint32 count = 0;
438 afs_uint32 old_enum = 0;
439 size_t space_limited = 0;
440 size_t space_available = 0;
441 afs_uint32 first_entry = 1;
445 RPC_SRVSVC_ShareEnumAgeCheck();
447 /* We only support one server name so ignore 'ServerName'. */
449 /* Test for unsupported level early */
450 switch (InfoStruct->Level) {
456 return ERROR_INVALID_LEVEL;
459 if (ResumeHandle && *ResumeHandle == 0xFFFFFFFF) {
460 /* No More Entries */
461 InfoStruct->ShareInfo.Level0->EntriesRead = 0;
462 return ERROR_NO_MORE_FILES;
465 /* get the directory size */
467 lock_ObtainWrite(&dscp->rw);
468 code = cm_SyncOp(dscp, NULL, userp, &req, PRSFS_LOOKUP,
469 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
471 lock_ReleaseWrite(&dscp->rw);
472 cm_ReleaseSCache(dscp);
473 osi_Log1(afsd_logp, "NetShareEnum cm_SyncOp failure code=0x%x", code);
477 cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
478 lock_ReleaseWrite(&dscp->rw);
480 if (dscp->fileType != CM_SCACHETYPE_DIRECTORY) {
481 cm_ReleaseSCache(dscp);
482 osi_Log1(afsd_logp, "NetShareEnum Not a Directory dscp=0x%p", dscp);
483 return ERROR_DIRECTORY;
487 * If there is no enumeration handle, then this is a new query
488 * and we must perform an enumeration for the specified object
490 if (ResumeHandle == NULL || *ResumeHandle == 0) {
493 code = cm_BeginDirOp(dscp, userp, &req, CM_DIRLOCK_READ, &dirop);
495 code = cm_BPlusDirEnumerate(dscp, userp, &req, TRUE, NULL, TRUE, &enump);
497 osi_Log1(afsd_logp, "NetShareEnum cm_BPlusDirEnumerate failure code=0x%x",
502 osi_Log1(afsd_logp, "NetShareEnum cm_BeginDirOp failure code=0x%x",
507 enump = RPC_SRVSVC_ShareEnumFind(*ResumeHandle);
512 cm_ReleaseSCache(dscp);
513 osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present");
515 return (code ? ERROR_BUSY : ERROR_SUCCESS);
519 * Do not exceed PreferredMaximumLength in any response.
520 * 0xFFFFFFFF means no limit.
522 * *TotalEntries is a hint of the total entries in the
523 * enumeration. It does not have to be exact. It is
524 * the same for each response in an enum.
526 * If *ResumeHandle == 0, this is an initial call
528 * The algorithm will be to enumerate the list of share
529 * names based upon the contents of the root.afs root
530 * directory. We will ignore SMB submount names.
531 * The enumeration will be valid for five minutes. If
532 * the enumeration is not destroyed within that time period
533 * it will be automatically garbage collected.
537 * How much space do we need and do we have that much room?
539 * If a preferred maximum length is specified, then we must
540 * manage the number of bytes we return in order to restrict
541 * it to a value smaller than then the preferred. This includes
542 * not only the InfoStruct but also the allocated SHARE_INFO
543 * buffer and the various C strings. We are not permitted to
544 * send incomplete values so we will send a value that is close.
546 if (PreferedMaximumLength != 0xFFFFFFFF) {
548 space_available = PreferedMaximumLength;
551 switch (InfoStruct->Level) {
554 space_available -= sizeof(InfoStruct->ShareInfo.Level2);
555 InfoStruct->ShareInfo.Level2->Buffer = calloc((enump->count - enump->next), sizeof(SHARE_INFO_2));
559 space_available -= sizeof(InfoStruct->ShareInfo.Level1);
560 InfoStruct->ShareInfo.Level1->Buffer = calloc((enump->count - enump->next), sizeof(SHARE_INFO_1));
564 space_available -= sizeof(InfoStruct->ShareInfo.Level0);
565 InfoStruct->ShareInfo.Level0->Buffer = calloc((enump->count - enump->next), sizeof(SHARE_INFO_0));
569 if (InfoStruct->ShareInfo.Level0->Buffer == NULL) {
570 cm_ReleaseSCache(dscp);
571 cm_BPlusDirFreeEnumeration(enump);
572 osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present");
573 return ERROR_NOT_ENOUGH_MEMORY;
580 code = cm_BPlusDirPeekNextEnumEntry(enump, &entryp);
582 code = cm_BPlusDirNextEnumEntry(enump, &entryp);
583 if (code != 0 && code != CM_ERROR_STOPNOW || entryp == NULL)
586 stopnow = (code == CM_ERROR_STOPNOW);
588 if ( !wcscmp(L".", entryp->name) || !wcscmp(L"..", entryp->name) ) {
589 osi_Log0(afsd_logp, "NetShareEnum skipping . or ..");
591 cm_BPlusDirNextEnumEntry(enump, &entryp);
595 cm_GetSCache(&entryp->fid, &scp, userp, &req);
597 switch (InfoStruct->Level) {
599 /* for share level security */
600 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_permissions = 0;
601 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_max_uses = -1;
602 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_current_uses = 0;
603 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path =
604 NetrIntGenerateSharePath(ServerName, &entryp->fid);
605 /* must be the empty string */
606 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_passwd = wcsdup(L"");
608 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_type = STYPE_DISKTREE;
609 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark =
610 NetrIntGenerateShareRemark(scp, &entryp->fid);
611 InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname = wcsdup(entryp->name);
614 InfoStruct->ShareInfo.Level1->Buffer[count].shi1_type = STYPE_DISKTREE;
615 InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark =
616 NetrIntGenerateShareRemark(scp, &entryp->fid);
617 InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname = wcsdup(entryp->name);
620 InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname = wcsdup(entryp->name);
624 cm_ReleaseSCache(scp);
629 * If space is limited, we need to determine if there is room
630 * for the next entry but always send at least one.
632 switch (InfoStruct->Level) {
634 space_used = sizeof(InfoStruct->ShareInfo.Level2->Buffer[count]) +
635 (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path) + 1) * sizeof(wchar_t) +
636 sizeof(wchar_t) + /* passwd */
637 (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark) + 1) * sizeof(wchar_t) +
638 (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname) + 1) * sizeof(wchar_t);
641 space_used = sizeof(InfoStruct->ShareInfo.Level1->Buffer[count]) +
642 (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark) + 1) * sizeof(wchar_t) +
643 (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname) + 1) * sizeof(wchar_t);
646 space_used = sizeof(InfoStruct->ShareInfo.Level0->Buffer[count]) +
647 (wcslen(InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname) + 1) * sizeof(wchar_t);
651 if (!first_entry && space_used > space_available)
654 /* Now consume the entry */
655 cm_BPlusDirNextEnumEntry(enump, &entryp);
656 space_available -= space_used;
661 InfoStruct->ShareInfo.Level0->EntriesRead = count;
662 *TotalEntries = enump->count;
664 cm_ReleaseSCache(dscp);
666 if (code || enump->next == enump->count || ResumeHandle == NULL) {
668 RPC_SRVSVC_ShareEnumRemove(enump);
669 cm_BPlusDirFreeEnumeration(enump);
671 *ResumeHandle = 0xFFFFFFFF;
672 return (code || enump->next == enump->count) ? 0 : ERROR_MORE_DATA;
674 *ResumeHandle = RPC_SRVSVC_ShareEnumSave(enump);
675 return ERROR_MORE_DATA;
679 NET_API_STATUS NetrShareGetInfo(
680 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
681 /* [string][in] */ WCHAR *NetName,
682 /* [in] */ DWORD Level,
683 /* [switch_is][out] */ LPSHARE_INFO InfoStruct)
685 cm_scache_t * dscp = cm_data.rootSCachep;
686 cm_scache_t * scp = NULL;
687 cm_user_t *userp = MSRPC_GetCmUser();
690 NET_API_STATUS status = 0;
692 /* make room for '/@vol:' + mountchar + NULL terminator*/
693 clientchar_t pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH];
698 /* Allocate the memory for the response */
701 InfoStruct->ShareInfo2 = calloc(1, sizeof(SHARE_INFO_2));
704 InfoStruct->ShareInfo1 = calloc(1, sizeof(SHARE_INFO_1));
707 InfoStruct->ShareInfo0 = calloc(1, sizeof(SHARE_INFO_0));
711 if (InfoStruct->ShareInfo0 == NULL) {
712 return ERROR_NOT_ENOUGH_MEMORY;
717 * 1.a an entry in the root.afs volume root directory
718 * 1.b an entry in the Freelance volume root directory
719 * 2. A volume reference: <cell><type><volume>
720 * 3. an SMB Submount name
721 * 4. a cell name that we do not yet have an entry
722 * for in the Freelance volume root directory
726 * To obtain the needed information for the response we
727 * need to obtain the cm_scache_t entry. First check to
728 * see if the NetName is a volume reference, then check
729 * if the NetName is an entry in the root volume root
730 * directory, finally we can check the SMB Submounts.
731 * Volume references and SMB submounts are not advertised
732 * as part of the Share enumerations but we should provide
733 * Share info for them nevertheless. Same for the secret
737 /* Check for volume references
739 * They look like <cell>{%,#}<volume>
741 if (cm_ClientStrChr(NetName, '%') != NULL ||
742 cm_ClientStrChr(NetName, '#') != NULL)
744 osi_Log1(afsd_logp, "NetrShareGetInfo found volume reference [%S]",
745 osi_LogSaveClientString(afsd_logp, NetName));
747 cm_ClientStrPrintfN(pathstr, lengthof(pathstr),
748 _C(CM_PREFIX_VOL) _C("%s"), NetName);
749 code = cm_Lookup(dscp, pathstr, 0, userp, &req, &scp);
750 } else if (cm_ClientStrCmpI(NetName, L"ALL") == 0) {
751 DWORD allSubmount = 1;
753 /* if allSubmounts == 0, only return the //mountRoot/all share
754 * if in fact it has been been created in the subMounts table.
755 * This is to allow sites that want to restrict access to the
758 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
759 0, KEY_QUERY_VALUE, &parmKey);
760 if (code == ERROR_SUCCESS) {
761 cblen = sizeof(allSubmount);
762 code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL,
763 (BYTE *) &allSubmount, &cblen);
764 if (code != ERROR_SUCCESS) {
767 RegCloseKey (parmKey);
776 * Could be a Submount, a directory entry, or a cell name we
777 * have yet to create an entry for.
780 /* Try a directory entry first */
781 code = cm_Lookup(dscp, NetName, CM_FLAG_NOMOUNTCHASE,
783 if (code && code != CM_ERROR_NOACCESS)
784 code = cm_Lookup(dscp, NetName, CM_FLAG_CASEFOLD | CM_FLAG_NOMOUNTCHASE,
787 if (scp == NULL && code != CM_ERROR_NOACCESS) { /* Try a submount */
788 code = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\OpenAFS\\Client\\Submounts",
789 0, KEY_QUERY_VALUE, &parmKey);
790 if (code == ERROR_SUCCESS) {
791 cblen = sizeof(pathstr);
792 code = RegQueryValueExW(parmKey, NetName, NULL, NULL,
793 (BYTE *) pathstr, &cblen);
794 if (code != ERROR_SUCCESS)
796 RegCloseKey (parmKey);
802 code = cm_NameI(dscp, pathstr, CM_FLAG_FOLLOW, userp, NULL, &req, &scp);
803 if (code && code != CM_ERROR_NOACCESS)
804 code = cm_NameI(dscp, pathstr, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
805 userp, NULL, &req, &scp);
813 /* for share level security */
814 InfoStruct->ShareInfo2->shi2_permissions = 0;
815 InfoStruct->ShareInfo2->shi2_max_uses = -1;
816 InfoStruct->ShareInfo2->shi2_current_uses = 0;
817 InfoStruct->ShareInfo2->shi2_path =
818 NetrIntGenerateSharePath(ServerName, &scp->fid);
819 /* must be the empty string */
820 InfoStruct->ShareInfo2->shi2_passwd = wcsdup(L"");
823 InfoStruct->ShareInfo1->shi1_type = STYPE_DISKTREE;
824 InfoStruct->ShareInfo1->shi1_remark =
825 NetrIntGenerateShareRemark(scp, &scp->fid);
828 /* Canonicalized version of NetName parameter */
829 InfoStruct->ShareInfo0->shi0_netname = wcsdup(NetName);
838 status = ERROR_INVALID_LEVEL;
840 cm_ReleaseSCache(scp);
843 * The requested object does not exist.
844 * Return the correct NERR or Win32 Error.
846 smb_MapWin32Error(code, &status);
848 case ERROR_FILE_NOT_FOUND:
849 case ERROR_PATH_NOT_FOUND:
850 case ERROR_INVALID_NAME:
851 case ERROR_BAD_NETPATH:
852 status = NERR_NetNameNotFound;
859 NET_API_STATUS NetrShareSetInfo(
860 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
861 /* [string][in] */ WCHAR *NetName,
862 /* [in] */ DWORD Level,
863 /* [switch_is][in] */ LPSHARE_INFO ShareInfo,
864 /* [unique][out][in] */ DWORD *ParmErr)
866 return ERROR_NOT_SUPPORTED;
869 NET_API_STATUS NetrShareDel(
870 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
871 /* [string][in] */ WCHAR *NetName,
872 /* [in] */ DWORD Reserved)
874 return ERROR_NOT_SUPPORTED;
877 NET_API_STATUS NetrShareDelSticky(
878 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
879 /* [string][in] */ WCHAR *NetName,
880 /* [in] */ DWORD Reserved)
882 return ERROR_NOT_SUPPORTED;
885 NET_API_STATUS NetrShareCheck(
886 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
887 /* [string][in] */ WCHAR *Device,
888 /* [out] */ DWORD *Type)
890 return ERROR_NOT_SUPPORTED;
893 NET_API_STATUS NetrServerGetInfo(
894 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
895 /* [in] */ DWORD Level,
896 /* [switch_is][out] */ LPSERVER_INFO InfoStruct)
899 * How much space do we need and do we have that much room?
900 * For now, just assume we can return everything in one shot
901 * because the reality is that in this function call we do
902 * not know the max size of the RPC response.
906 InfoStruct->ServerInfo103 = calloc(1, sizeof(SERVER_INFO_103));
909 InfoStruct->ServerInfo102 = calloc(1, sizeof(SERVER_INFO_102));
912 InfoStruct->ServerInfo101 = calloc(1, sizeof(SERVER_INFO_101));
915 InfoStruct->ServerInfo100 = calloc(1, sizeof(SERVER_INFO_100));
919 if (InfoStruct->ServerInfo100 == NULL) {
920 return ERROR_NOT_ENOUGH_MEMORY;
925 InfoStruct->ServerInfo103->sv103_capabilities = 0;
928 InfoStruct->ServerInfo102->sv102_users = 0xFFFFFFFF;
929 InfoStruct->ServerInfo102->sv102_disc = SV_NODISC;
930 InfoStruct->ServerInfo102->sv102_hidden = SV_HIDDEN;
931 InfoStruct->ServerInfo102->sv102_announce = 65535;
932 InfoStruct->ServerInfo102->sv102_anndelta = 0;
933 InfoStruct->ServerInfo102->sv102_licenses = 0;
934 InfoStruct->ServerInfo102->sv102_userpath = wcsdup(L"C:\\");
937 InfoStruct->ServerInfo101->sv101_version_major = AFSPRODUCT_VERSION_MAJOR;
938 InfoStruct->ServerInfo101->sv101_version_minor = AFSPRODUCT_VERSION_MINOR;
939 InfoStruct->ServerInfo101->sv101_type = SV_TYPE_SERVER_UNIX;
940 InfoStruct->ServerInfo101->sv101_comment = wcsdup(wAFSVersion);
943 InfoStruct->ServerInfo100->sv100_platform_id = SV_PLATFORM_ID_AFS;
944 /* The Netbios Name */
945 InfoStruct->ServerInfo100->sv100_name = wcsdup(ServerName);
995 return ERROR_INVALID_LEVEL;
1000 NET_API_STATUS NetrServerSetInfo(
1001 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1002 /* [in] */ DWORD Level,
1003 /* [switch_is][in] */ LPSERVER_INFO ServerInfo,
1004 /* [unique][out][in] */ DWORD *ParmErr)
1006 return ERROR_NOT_SUPPORTED;
1009 NET_API_STATUS NetrServerDiskEnum(
1010 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1011 /* [in] */ DWORD Level,
1012 /* [out][in] */ DISK_ENUM_CONTAINER *DiskInfoStruct,
1013 /* [in] */ DWORD PreferedMaximumLength,
1014 /* [out] */ DWORD *TotalEntries,
1015 /* [unique][out][in] */ DWORD *ResumeHandle)
1017 return ERROR_NOT_SUPPORTED;
1020 NET_API_STATUS NetrServerStatisticsGet(
1021 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1022 /* [unique][string][in] */ WCHAR *Service,
1023 /* [in] */ DWORD Level,
1024 /* [in] */ DWORD Options,
1025 /* [out] */ LPSTAT_SERVER_0 *InfoStruct)
1027 return ERROR_NOT_SUPPORTED;
1030 NET_API_STATUS NetrServerTransportAdd(
1031 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1032 /* [in] */ DWORD Level,
1033 /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer)
1035 return ERROR_NOT_SUPPORTED;
1038 NET_API_STATUS NetrServerTransportEnum(
1039 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1040 /* [out][in] */ LPSERVER_XPORT_ENUM_STRUCT InfoStruct,
1041 /* [in] */ DWORD PreferedMaximumLength,
1042 /* [out] */ DWORD *TotalEntries,
1043 /* [unique][out][in] */ DWORD *ResumeHandle)
1045 return ERROR_NOT_SUPPORTED;
1048 NET_API_STATUS NetrServerTransportDel(
1049 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1050 /* [in] */ DWORD Level,
1051 /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer)
1053 return ERROR_NOT_SUPPORTED;
1056 NET_API_STATUS NetrRemoteTOD(
1057 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1058 /* [out] */ LPTIME_OF_DAY_INFO *BufferPtr)
1060 return ERROR_NOT_SUPPORTED;
1063 NET_API_STATUS NetprPathType(
1064 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1065 /* [string][in] */ WCHAR *PathName,
1066 /* [out] */ DWORD *PathType,
1067 /* [in] */ DWORD Flags)
1069 return ERROR_NOT_SUPPORTED;
1072 NET_API_STATUS NetprPathCanonicalize(
1073 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1074 /* [string][in] */ WCHAR *PathName,
1075 /* [size_is][out] */ unsigned char *Outbuf,
1076 /* [range][in] */ DWORD OutbufLen,
1077 /* [string][in] */ WCHAR *Prefix,
1078 /* [out][in] */ DWORD *PathType,
1079 /* [in] */ DWORD Flags)
1081 return ERROR_NOT_SUPPORTED;
1084 long NetprPathCompare(
1085 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1086 /* [string][in] */ WCHAR *PathName1,
1087 /* [string][in] */ WCHAR *PathName2,
1088 /* [in] */ DWORD PathType,
1089 /* [in] */ DWORD Flags)
1091 return ERROR_NOT_SUPPORTED;
1094 NET_API_STATUS NetprNameValidate(
1095 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1096 /* [string][in] */ WCHAR *Name,
1097 /* [in] */ DWORD NameType,
1098 /* [in] */ DWORD Flags)
1100 return ERROR_NOT_SUPPORTED;
1103 NET_API_STATUS NetprNameCanonicalize(
1104 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1105 /* [string][in] */ WCHAR *Name,
1106 /* [size_is][out] */ WCHAR *Outbuf,
1107 /* [range][in] */ DWORD OutbufLen,
1108 /* [in] */ DWORD NameType,
1109 /* [in] */ DWORD Flags)
1111 return ERROR_NOT_SUPPORTED;
1114 long NetprNameCompare(
1115 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1116 /* [string][in] */ WCHAR *Name1,
1117 /* [string][in] */ WCHAR *Name2,
1118 /* [in] */ DWORD NameType,
1119 /* [in] */ DWORD Flags)
1121 return ERROR_NOT_SUPPORTED;
1124 NET_API_STATUS NetrShareEnumSticky(
1125 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1126 /* [out][in] */ LPSHARE_ENUM_STRUCT InfoStruct,
1127 /* [in] */ DWORD PreferedMaximumLength,
1128 /* [out] */ DWORD *TotalEntries,
1129 /* [unique][out][in] */ DWORD *ResumeHandle)
1131 return ERROR_NOT_SUPPORTED;
1134 NET_API_STATUS NetrShareDelStart(
1135 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1136 /* [string][in] */ WCHAR *NetName,
1137 /* [in] */ DWORD Reserved,
1138 /* [out] */ PSHARE_DEL_HANDLE ContextHandle)
1140 return ERROR_NOT_SUPPORTED;
1143 NET_API_STATUS NetrShareDelCommit(
1144 /* [out][in] */ PSHARE_DEL_HANDLE ContextHandle)
1146 return ERROR_NOT_SUPPORTED;
1149 DWORD NetrpGetFileSecurity(
1150 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1151 /* [unique][string][in] */ WCHAR *ShareName,
1152 /* [string][in] */ WCHAR *lpFileName,
1153 /* [in] */ SECURITY_INFORMATION RequestedInformation,
1154 /* [out] */ PADT_SECURITY_DESCRIPTOR *SecurityDescriptor)
1156 return ERROR_NOT_SUPPORTED;
1159 DWORD NetrpSetFileSecurity(
1160 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1161 /* [unique][string][in] */ WCHAR *ShareName,
1162 /* [string][in] */ WCHAR *lpFileName,
1163 /* [in] */ SECURITY_INFORMATION SecurityInformation,
1164 /* [in] */ PADT_SECURITY_DESCRIPTOR SecurityDescriptor)
1166 return ERROR_NOT_SUPPORTED;
1169 NET_API_STATUS NetrServerTransportAddEx(
1170 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1171 /* [in] */ DWORD Level,
1172 /* [switch_is][in] */ LPTRANSPORT_INFO Buffer)
1174 return ERROR_NOT_SUPPORTED;
1177 NET_API_STATUS NetrDfsGetVersion(
1178 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1179 /* [out] */ DWORD *Version)
1181 return ERROR_NOT_SUPPORTED;
1184 NET_API_STATUS NetrDfsCreateLocalPartition(
1185 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1186 /* [string][in] */ WCHAR *ShareName,
1187 /* [in] */ GUID *EntryUid,
1188 /* [string][in] */ WCHAR *EntryPrefix,
1189 /* [string][in] */ WCHAR *ShortName,
1190 /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo,
1191 /* [in] */ int Force)
1193 return ERROR_NOT_SUPPORTED;
1196 NET_API_STATUS NetrDfsDeleteLocalPartition(
1197 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1198 /* [in] */ GUID *Uid,
1199 /* [string][in] */ WCHAR *Prefix)
1201 return ERROR_NOT_SUPPORTED;
1204 NET_API_STATUS NetrDfsSetLocalVolumeState(
1205 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1206 /* [in] */ GUID *Uid,
1207 /* [string][in] */ WCHAR *Prefix,
1208 /* [in] */ unsigned long State)
1210 return ERROR_NOT_SUPPORTED;
1213 NET_API_STATUS NetrDfsCreateExitPoint(
1214 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1215 /* [in] */ GUID *Uid,
1216 /* [string][in] */ WCHAR *Prefix,
1217 /* [in] */ unsigned long Type,
1218 /* [range][in] */ DWORD ShortPrefixLen,
1219 /* [size_is][string][out] */ WCHAR *ShortPrefix)
1221 return ERROR_NOT_SUPPORTED;
1224 NET_API_STATUS NetrDfsDeleteExitPoint(
1225 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1226 /* [in] */ GUID *Uid,
1227 /* [string][in] */ WCHAR *Prefix,
1228 /* [in] */ unsigned long Type)
1230 return ERROR_NOT_SUPPORTED;
1233 NET_API_STATUS NetrDfsModifyPrefix(
1234 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1235 /* [in] */ GUID *Uid,
1236 /* [string][in] */ WCHAR *Prefix)
1238 return ERROR_NOT_SUPPORTED;
1241 NET_API_STATUS NetrDfsFixLocalVolume(
1242 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1243 /* [string][in] */ WCHAR *VolumeName,
1244 /* [in] */ unsigned long EntryType,
1245 /* [in] */ unsigned long ServiceType,
1246 /* [string][in] */ WCHAR *StgId,
1247 /* [in] */ GUID *EntryUid,
1248 /* [string][in] */ WCHAR *EntryPrefix,
1249 /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo,
1250 /* [in] */ unsigned long CreateDisposition)
1252 return ERROR_NOT_SUPPORTED;
1255 NET_API_STATUS NetrDfsManagerReportSiteInfo(
1256 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1257 /* [unique][out][in] */ LPDFS_SITELIST_INFO *ppSiteInfo)
1259 return ERROR_NOT_SUPPORTED;
1262 NET_API_STATUS NetrServerTransportDelEx(
1263 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1264 /* [in] */ DWORD Level,
1265 /* [switch_is][in] */ LPTRANSPORT_INFO Buffer)
1267 return ERROR_NOT_SUPPORTED;
1270 NET_API_STATUS NetrServerAliasAdd(
1271 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1272 /* [in] */ DWORD Level,
1273 /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct)
1275 return ERROR_NOT_SUPPORTED;
1278 NET_API_STATUS NetrServerAliasEnum(
1279 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1280 /* [out][in] */ LPSERVER_ALIAS_ENUM_STRUCT InfoStruct,
1281 /* [in] */ DWORD PreferedMaximumLength,
1282 /* [out] */ LPDWORD TotalEntries,
1283 /* [unique][out][in] */ LPDWORD ResumeHandle)
1285 return ERROR_NOT_SUPPORTED;
1288 NET_API_STATUS NetrServerAliasDel(
1289 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1290 /* [in] */ DWORD Level,
1291 /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct)
1293 return ERROR_NOT_SUPPORTED;
1296 NET_API_STATUS NetrShareDelEx(
1297 /* [unique][string][in] */ SRVSVC_HANDLE ServerName,
1298 /* [in] */ DWORD Level,
1299 /* [switch_is][in] */ LPSHARE_INFO ShareInfo)
1301 return ERROR_NOT_SUPPORTED;
1305 void __RPC_USER SHARE_DEL_HANDLE_rundown( SHARE_DEL_HANDLE h)
1309 /* [nocode] */ void Opnum0NotUsedOnWire(
1310 /* [in] */ handle_t IDL_handle)
1314 /* [nocode] */ void Opnum1NotUsedOnWire(
1315 /* [in] */ handle_t IDL_handle)
1319 /* [nocode] */ void Opnum2NotUsedOnWire(
1320 /* [in] */ handle_t IDL_handle)
1325 /* [nocode] */ void Opnum3NotUsedOnWire(
1326 /* [in] */ handle_t IDL_handle)
1330 /* [nocode] */ void Opnum4NotUsedOnWire(
1331 /* [in] */ handle_t IDL_handle)
1336 /* [nocode] */ void Opnum5NotUsedOnWire(
1337 /* [in] */ handle_t IDL_handle)
1341 /* [nocode] */ void Opnum6NotUsedOnWire(
1342 /* [in] */ handle_t IDL_handle)
1346 /* [nocode] */ void Opnum7NotUsedOnWire(
1347 /* [in] */ handle_t IDL_handle)
1351 /* [nocode] */ void Opnum29NotUsedOnWire(
1352 /* [in] */ handle_t IDL_handle)
1356 /* [nocode] */ void Opnum42NotUsedOnWire(
1357 /* [in] */ handle_t IDL_handle)
1361 /* [nocode] */ void Opnum47NotUsedOnWire(
1362 /* [in] */ handle_t IDL_handle)