/* * Copyright (c) 2009 Secure Endpoints Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include #include #define _CRT_RAND_S #include #include #include #include "ms-srvsvc.h" #include "msrpc.h" #include "afsd.h" #include "smb.h" #include #define AFS_VERSION_STRINGS #include "AFS_component_version_number.h" #pragma warning( disable: 4027 ) /* func w/o formal parameter list */ /* Do not pull in lmserver.h */ // // The platform ID indicates the levels to use for platform-specific // information. // #define SV_PLATFORM_ID_DOS 300 #define SV_PLATFORM_ID_OS2 400 #define SV_PLATFORM_ID_NT 500 #define SV_PLATFORM_ID_OSF 600 #define SV_PLATFORM_ID_VMS 700 #define SV_PLATFORM_ID_AFS 800 // // Bit-mapped values for svX_type fields. X = 1, 2 or 3. // #define SV_TYPE_WORKSTATION 0x00000001 #define SV_TYPE_SERVER 0x00000002 #define SV_TYPE_SQLSERVER 0x00000004 #define SV_TYPE_DOMAIN_CTRL 0x00000008 #define SV_TYPE_DOMAIN_BAKCTRL 0x00000010 #define SV_TYPE_TIME_SOURCE 0x00000020 #define SV_TYPE_AFP 0x00000040 #define SV_TYPE_NOVELL 0x00000080 #define SV_TYPE_DOMAIN_MEMBER 0x00000100 #define SV_TYPE_PRINTQ_SERVER 0x00000200 #define SV_TYPE_DIALIN_SERVER 0x00000400 #define SV_TYPE_XENIX_SERVER 0x00000800 #define SV_TYPE_SERVER_UNIX SV_TYPE_XENIX_SERVER #define SV_TYPE_NT 0x00001000 #define SV_TYPE_WFW 0x00002000 #define SV_TYPE_SERVER_MFPN 0x00004000 #define SV_TYPE_SERVER_NT 0x00008000 #define SV_TYPE_POTENTIAL_BROWSER 0x00010000 #define SV_TYPE_BACKUP_BROWSER 0x00020000 #define SV_TYPE_MASTER_BROWSER 0x00040000 #define SV_TYPE_DOMAIN_MASTER 0x00080000 #define SV_TYPE_SERVER_OSF 0x00100000 #define SV_TYPE_SERVER_VMS 0x00200000 #define SV_TYPE_WINDOWS 0x00400000 /* Windows95 and above */ #define SV_TYPE_DFS 0x00800000 /* Root of a DFS tree */ #define SV_TYPE_CLUSTER_NT 0x01000000 /* NT Cluster */ #define SV_TYPE_TERMINALSERVER 0x02000000 /* Terminal Server(Hydra) */ #define SV_TYPE_CLUSTER_VS_NT 0x04000000 /* NT Cluster Virtual Server Name */ #define SV_TYPE_DCE 0x10000000 /* IBM DSS (Directory and Security Services) or equivalent */ #define SV_TYPE_ALTERNATE_XPORT 0x20000000 /* return list for alternate transport */ #define SV_TYPE_LOCAL_LIST_ONLY 0x40000000 /* Return local list only */ #define SV_TYPE_DOMAIN_ENUM 0x80000000 #define SV_TYPE_ALL 0xFFFFFFFF /* handy for NetServerEnum2 */ // // Values of svX_hidden field. X = 2 or 3. // #define SV_HIDDEN 1 #define SV_VISIBLE 0 NET_API_STATUS NetrConnectionEnum( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][string][in] */ WCHAR *Qualifier, /* [out][in] */ LPCONNECT_ENUM_STRUCT InfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ DWORD *TotalEntries, /* [unique][out][in] */ DWORD *ResumeHandle) { osi_Log0(afsd_logp, "NetrConnectionEnum not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrFileEnum( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][string][in] */ WCHAR *BasePath, /* [unique][string][in] */ WCHAR *UserName, /* [out][in] */ PFILE_ENUM_STRUCT InfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ DWORD *TotalEntries, /* [unique][out][in] */ DWORD *ResumeHandle) { osi_Log0(afsd_logp, "NetrFileEnum not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrFileGetInfo( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD FileId, /* [in] */ DWORD Level, /* [switch_is][out] */ LPFILE_INFO InfoStruct) { osi_Log0(afsd_logp, "NetrFileGetInfo not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrFileClose( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD FileId) { osi_Log0(afsd_logp, "NetrFileClose not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrSessionEnum( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][string][in] */ WCHAR *ClientName, /* [unique][string][in] */ WCHAR *UserName, /* [out][in] */ PSESSION_ENUM_STRUCT InfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ DWORD *TotalEntries, /* [unique][out][in] */ DWORD *ResumeHandle) { osi_Log0(afsd_logp, "NetrSessionEnum not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrSessionDel( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][string][in] */ WCHAR *ClientName, /* [unique][string][in] */ WCHAR *UserName) { osi_Log0(afsd_logp, "NetrSessionDel not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareAdd( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPSHARE_INFO InfoStruct, /* [unique][out][in] */ DWORD *ParmErr) { osi_Log0(afsd_logp, "NetrShareAdd not supported"); return ERROR_NOT_SUPPORTED; } static wchar_t * NetrIntGenerateShareRemark(cm_scache_t *scp, cm_fid_t *fidp) { wchar_t remark[1536], *s, *wcellname, *wmp; HRESULT hr; cm_cell_t *cellp; afs_int32 b; cellp = cm_FindCellByID(fidp->cell, CM_FLAG_NOPROBE); if (cellp) wcellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL); else wcellname = L""; if (scp) { switch (scp->fileType) { case 1: hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS File (%s:%u.%u.%u)", wcellname, scp->fid.volume, scp->fid.vnode, scp->fid.unique); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS File"); break; case 2: hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS Directory (%s:%u.%u.%u)", wcellname, scp->fid.volume, scp->fid.vnode, scp->fid.unique); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS Directory"); break; case 3: wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL); hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS Symlink to %s", wmp ? wmp : L""); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS Symlink"); if (wmp) free(wmp); break; case 4: b = (strchr(scp->mountPointStringp, ':') != NULL); wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL); hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS MountPoint to %s%s%s%s", wmp ? wmp : L"", b ? L"" : L" (", b ? L"" : wcellname, b ? L"" : L")"); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS MountPoint"); if (wmp) free(wmp); break; case 5: wmp = cm_FsStringToClientStringAlloc(scp->mountPointStringp, -1, NULL); hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS Dfslink to %s", wmp ? wmp : L""); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS DfsLink"); if (wmp) free(wmp); break; default: hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS Object (%s:%u.%u.%u)", wcellname, scp->fid.volume, scp->fid.vnode, scp->fid.unique); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS Object"); } } else { if (fidp->vnode & 1) { hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS Directory (%s:%u.%u.%u)", wcellname, fidp->volume, fidp->vnode, fidp->unique); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS Directory"); } else { hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"AFS Object (%s:%u.%u.%u)", wcellname, fidp->volume, fidp->vnode, fidp->unique); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L"AFS Object"); } } if (cellp && wcellname) free(wcellname); return s; } static wchar_t * NetrIntGenerateSharePath(wchar_t *ServerName, cm_fid_t *fidp) { wchar_t remark[1536], *s, *wcellname; HRESULT hr; cm_cell_t *cellp; cellp = cm_FindCellByID(fidp->cell, CM_FLAG_NOPROBE); if (cellp) wcellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL); else wcellname = L""; for ( s=ServerName; *s == '\\' || *s == '/'; s++); hr = StringCchPrintfW( remark, sizeof(remark)/sizeof(remark[0]), L"\\\\%s\\%s\\%u.%u.%u", s, wcellname, fidp->volume, fidp->vnode, fidp->unique); if (hr == S_OK) s = wcsdup(remark); else s = wcsdup(L""); if (cellp && wcellname) free(wcellname); return s; } typedef struct netr_share_enum { osi_queue_t q; time_t cleanup_time; DWORD handle; cm_direnum_t *direnump; } netr_share_enum_t; static osi_queue_t * shareEnumQ = NULL; static osi_mutex_t shareEnum_mx; static DWORD shareEnum_next_handle=1; void RPC_SRVSVC_Init(void) { #if _MSC_VER >= 1400 int hasRand_s = -1; OSVERSIONINFO osInfo; osInfo.dwOSVersionInfoSize = sizeof(osInfo); if (GetVersionEx(&osInfo)) { if ((osInfo.dwMajorVersion > 5) || (osInfo.dwMajorVersion == 5) && (osInfo.dwMinorVersion >= 1)) hasRand_s = 1; else hasRand_s = 0; } #endif lock_InitializeMutex(&shareEnum_mx, "NetrShareEnum", 0); shareEnumQ = NULL; #if _MSC_VER >= 1400 if (hasRand_s > 0) { rand_s(&shareEnum_next_handle); } else #endif { srand((unsigned) time( NULL )); shareEnum_next_handle = rand(); } } void RPC_SRVSVC_Shutdown(void) { netr_share_enum_t *enump; lock_ObtainMutex(&shareEnum_mx); while (shareEnumQ) { enump = (netr_share_enum_t *)shareEnumQ; cm_BPlusDirFreeEnumeration(enump->direnump); osi_QRemove(&shareEnumQ, (osi_queue_t *)enump); free(enump); } lock_FinalizeMutex(&shareEnum_mx); } static void RPC_SRVSVC_ShareEnumAgeCheck(void) { netr_share_enum_t *enump, *enumnp; time_t now; lock_ObtainMutex(&shareEnum_mx); now = time(NULL); for (enump = (netr_share_enum_t *)shareEnumQ; enump; enump = enumnp) { enumnp = (netr_share_enum_t *) osi_QNext(&(enump->q)); if (now > enump->cleanup_time) osi_QRemove(&shareEnumQ, (osi_queue_t *)enump); } lock_ReleaseMutex(&shareEnum_mx); } static cm_direnum_t * RPC_SRVSVC_ShareEnumFind(DWORD ResumeHandle) { netr_share_enum_t *enump; lock_ObtainMutex(&shareEnum_mx); for (enump = (netr_share_enum_t *)shareEnumQ; enump; enump = (netr_share_enum_t *) osi_QNext(&enump->q)) { if (ResumeHandle == enump->handle) break; } lock_ReleaseMutex(&shareEnum_mx); return enump ? enump->direnump : NULL; } static DWORD RPC_SRVSVC_ShareEnumSave(cm_direnum_t *direnump) { netr_share_enum_t *enump = (netr_share_enum_t *)malloc(sizeof(netr_share_enum_t)); if (enump == NULL) return 0xFFFFFFFF; lock_ObtainMutex(&shareEnum_mx); enump->cleanup_time = time(NULL) + 300; enump->handle = shareEnum_next_handle++; if (shareEnum_next_handle == 0xFFFFFFFF) shareEnum_next_handle = 1; enump->direnump = direnump; osi_QAdd(&shareEnumQ, (osi_queue_t *)enump); lock_ReleaseMutex(&shareEnum_mx); return enump->handle; } static void RPC_SRVSVC_ShareEnumRemove(cm_direnum_t *direnump) { netr_share_enum_t *enump; lock_ObtainMutex(&shareEnum_mx); for (enump = (netr_share_enum_t *)shareEnumQ; enump; enump = (netr_share_enum_t *) osi_QNext(&enump->q)) { if (direnump == enump->direnump) { osi_QRemove(&shareEnumQ, (osi_queue_t *)enump); break; } } lock_ReleaseMutex(&shareEnum_mx); } NET_API_STATUS NetrShareEnum( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [out][in] */ LPSHARE_ENUM_STRUCT InfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ DWORD *TotalEntries, /* [unique][out][in] */ DWORD *ResumeHandle) { cm_direnum_t *enump = NULL; cm_direnum_entry_t * entryp = NULL; cm_scache_t * dscp; cm_user_t *userp = MSRPC_GetCmUser(); cm_req_t req; int stopnow = 0; afs_uint32 count = 0; afs_uint32 code; afs_uint32 old_enum = 0; size_t space_limited = 0; size_t space_available = 0; afs_uint32 first_entry = 1; osi_Log1(afsd_logp, "NetrShareEnum level %u", InfoStruct->Level); cm_InitReq(&req); dscp = cm_RootSCachep(userp, &req); RPC_SRVSVC_ShareEnumAgeCheck(); /* We only support one server name so ignore 'ServerName'. */ /* Test for unsupported level early */ switch (InfoStruct->Level) { case 2: case 1: case 0: break; default: return ERROR_INVALID_LEVEL; } if (ResumeHandle && *ResumeHandle == 0xFFFFFFFF) { /* No More Entries */ InfoStruct->ShareInfo.Level0->EntriesRead = 0; return ERROR_NO_MORE_FILES; } /* get the directory size */ cm_HoldSCache(dscp); lock_ObtainWrite(&dscp->rw); code = cm_SyncOp(dscp, NULL, userp, &req, PRSFS_LOOKUP, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) { lock_ReleaseWrite(&dscp->rw); cm_ReleaseSCache(dscp); osi_Log1(afsd_logp, "NetShareEnum cm_SyncOp failure code=0x%x", code); return ERROR_BUSY; } cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); lock_ReleaseWrite(&dscp->rw); if (dscp->fileType != CM_SCACHETYPE_DIRECTORY) { cm_ReleaseSCache(dscp); osi_Log1(afsd_logp, "NetShareEnum Not a Directory dscp=0x%p", dscp); return ERROR_DIRECTORY; } /* * If there is no enumeration handle, then this is a new query * and we must perform an enumeration for the specified object */ if (ResumeHandle == NULL || *ResumeHandle == 0) { cm_dirOp_t dirop; code = cm_BeginDirOp(dscp, userp, &req, CM_DIRLOCK_READ, CM_DIROP_FLAG_NONE, &dirop); if (code == 0) { code = cm_BPlusDirEnumerate(dscp, userp, &req, TRUE, NULL, TRUE, &enump); if (code) { osi_Log1(afsd_logp, "NetShareEnum cm_BPlusDirEnumerate failure code=0x%x", code); } cm_EndDirOp(&dirop); } else { osi_Log1(afsd_logp, "NetShareEnum cm_BeginDirOp failure code=0x%x", code); } old_enum = 0; } else { enump = RPC_SRVSVC_ShareEnumFind(*ResumeHandle); old_enum = 1; } if (enump == NULL) { cm_ReleaseSCache(dscp); osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present"); *TotalEntries = 0; return (code ? ERROR_BUSY : ERROR_SUCCESS); } /* * Do not exceed PreferredMaximumLength in any response. * 0xFFFFFFFF means no limit. * * *TotalEntries is a hint of the total entries in the * enumeration. It does not have to be exact. It is * the same for each response in an enum. * * If *ResumeHandle == 0, this is an initial call * * The algorithm will be to enumerate the list of share * names based upon the contents of the root.afs root * directory. We will ignore SMB submount names. * The enumeration will be valid for five minutes. If * the enumeration is not destroyed within that time period * it will be automatically garbage collected. */ /* * How much space do we need and do we have that much room? * * If a preferred maximum length is specified, then we must * manage the number of bytes we return in order to restrict * it to a value smaller than then the preferred. This includes * not only the InfoStruct but also the allocated SHARE_INFO * buffer and the various C strings. We are not permitted to * send incomplete values so we will send a value that is close. */ if (PreferedMaximumLength != 0xFFFFFFFF) { space_limited = 1; space_available = PreferedMaximumLength; } switch (InfoStruct->Level) { case 2: if (space_limited) space_available -= sizeof(InfoStruct->ShareInfo.Level2); InfoStruct->ShareInfo.Level2->Buffer = MIDL_user_allocate((enump->count - enump->next) * sizeof(SHARE_INFO_2)); break; case 1: if (space_limited) space_available -= sizeof(InfoStruct->ShareInfo.Level1); InfoStruct->ShareInfo.Level1->Buffer = MIDL_user_allocate((enump->count - enump->next) * sizeof(SHARE_INFO_1)); break; case 0: if (space_limited) space_available -= sizeof(InfoStruct->ShareInfo.Level0); InfoStruct->ShareInfo.Level0->Buffer = MIDL_user_allocate((enump->count - enump->next) * sizeof(SHARE_INFO_0)); break; } if (InfoStruct->ShareInfo.Level0->Buffer == NULL) { cm_ReleaseSCache(dscp); cm_BPlusDirFreeEnumeration(enump); osi_Log0(afsd_logp, "NetShareEnum No Enumeration Present"); return ERROR_NOT_ENOUGH_MEMORY; } while (!stopnow) { cm_scache_t *scp; if (space_limited) code = cm_BPlusDirPeekNextEnumEntry(enump, &entryp); else code = cm_BPlusDirNextEnumEntry(enump, &entryp); if (code != 0 && code != CM_ERROR_STOPNOW || entryp == NULL) break; stopnow = (code == CM_ERROR_STOPNOW); if ( !wcscmp(L".", entryp->name) || !wcscmp(L"..", entryp->name) ) { osi_Log0(afsd_logp, "NetShareEnum skipping . or .."); if (space_limited) cm_BPlusDirNextEnumEntry(enump, &entryp); continue; } cm_GetSCache(&entryp->fid, NULL, &scp, userp, &req); switch (InfoStruct->Level) { case 2: /* for share level security */ InfoStruct->ShareInfo.Level2->Buffer[count].shi2_permissions = 0; InfoStruct->ShareInfo.Level2->Buffer[count].shi2_max_uses = -1; InfoStruct->ShareInfo.Level2->Buffer[count].shi2_current_uses = 0; InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path = NetrIntGenerateSharePath(ServerName, &entryp->fid); /* must be the empty string */ InfoStruct->ShareInfo.Level2->Buffer[count].shi2_passwd = wcsdup(L""); InfoStruct->ShareInfo.Level2->Buffer[count].shi2_type = STYPE_DISKTREE; InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark = NetrIntGenerateShareRemark(scp, &entryp->fid); InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname = wcsdup(entryp->name); break; case 1: InfoStruct->ShareInfo.Level1->Buffer[count].shi1_type = STYPE_DISKTREE; InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark = NetrIntGenerateShareRemark(scp, &entryp->fid); InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname = wcsdup(entryp->name); break; case 0: InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname = wcsdup(entryp->name); } if (scp) cm_ReleaseSCache(scp); if (space_limited) { size_t space_used; /* * If space is limited, we need to determine if there is room * for the next entry but always send at least one. */ switch (InfoStruct->Level) { case 2: space_used = sizeof(InfoStruct->ShareInfo.Level2->Buffer[count]) + (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_path) + 1) * sizeof(wchar_t) + sizeof(wchar_t) + /* passwd */ (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_remark) + 1) * sizeof(wchar_t) + (wcslen(InfoStruct->ShareInfo.Level2->Buffer[count].shi2_netname) + 1) * sizeof(wchar_t); break; case 1: space_used = sizeof(InfoStruct->ShareInfo.Level1->Buffer[count]) + (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_remark) + 1) * sizeof(wchar_t) + (wcslen(InfoStruct->ShareInfo.Level1->Buffer[count].shi1_netname) + 1) * sizeof(wchar_t); break; case 0: space_used = sizeof(InfoStruct->ShareInfo.Level0->Buffer[count]) + (wcslen(InfoStruct->ShareInfo.Level0->Buffer[count].shi0_netname) + 1) * sizeof(wchar_t); break; } if (!first_entry && space_used > space_available) break; /* Now consume the entry */ cm_BPlusDirNextEnumEntry(enump, &entryp); space_available -= space_used; } count++; first_entry = 0; } InfoStruct->ShareInfo.Level0->EntriesRead = count; *TotalEntries = enump->count; if (dscp) cm_ReleaseSCache(dscp); if (code || enump->next == enump->count || ResumeHandle == NULL) { if (old_enum) RPC_SRVSVC_ShareEnumRemove(enump); cm_BPlusDirFreeEnumeration(enump); if (ResumeHandle) *ResumeHandle = 0xFFFFFFFF; return (code || enump->next == enump->count) ? 0 : ERROR_MORE_DATA; } else { *ResumeHandle = RPC_SRVSVC_ShareEnumSave(enump); return ERROR_MORE_DATA; } } NET_API_STATUS NetrShareGetInfo( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *NetName, /* [in] */ DWORD Level, /* [switch_is][out] */ LPSHARE_INFO InfoStruct) { cm_scache_t * dscp; cm_scache_t * scp = NULL; cm_user_t *userp = MSRPC_GetCmUser(); cm_req_t req; afs_uint32 code = 0; NET_API_STATUS status = 0; HKEY parmKey; /* make room for '/@vol:' + mountchar + NULL terminator*/ clientchar_t pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH]; DWORD cblen; osi_Log1(afsd_logp, "NetrShareGetInfo level %u", Level); cm_InitReq(&req); dscp = cm_RootSCachep(userp, &req); InfoStruct->ShareInfo0 = NULL; /* * NetName will be: * 1.a an entry in the root.afs volume root directory * 1.b an entry in the Freelance volume root directory * 2. A volume reference: * 3. an SMB Submount name * 4. a cell name that we do not yet have an entry * for in the Freelance volume root directory */ /* * To obtain the needed information for the response we * need to obtain the cm_scache_t entry. First check to * see if the NetName is a volume reference, then check * if the NetName is an entry in the root volume root * directory, finally we can check the SMB Submounts. * Volume references and SMB submounts are not advertised * as part of the Share enumerations but we should provide * Share info for them nevertheless. Same for the secret * "all" share. */ /* Check for volume references * * They look like {%,#} */ if (cm_ClientStrChr(NetName, '%') != NULL || cm_ClientStrChr(NetName, '#') != NULL) { osi_Log1(afsd_logp, "NetrShareGetInfo found volume reference [%S]", osi_LogSaveClientString(afsd_logp, NetName)); cm_ClientStrPrintfN(pathstr, lengthof(pathstr), _C(CM_PREFIX_VOL) _C("%s"), NetName); code = cm_Lookup(dscp, pathstr, 0, userp, &req, &scp); } else if (cm_ClientStrCmpI(NetName, L"ALL") == 0) { DWORD allSubmount = 1; /* if allSubmounts == 0, only return the //mountRoot/all share * if in fact it has been been created in the subMounts table. * This is to allow sites that want to restrict access to the * world to do so. */ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { cblen = sizeof(allSubmount); code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL, (BYTE *) &allSubmount, &cblen); if (code != ERROR_SUCCESS) { allSubmount = 1; } RegCloseKey (parmKey); } if (allSubmount) { scp = dscp; cm_HoldSCache(scp); code = 0; } else { code = CM_ERROR_NOSUCHPATH; } } else { /* * Could be a Submount, a directory entry, or a cell name we * have yet to create an entry for. */ /* Try a directory entry first */ code = cm_Lookup(dscp, NetName, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); if (code && code != CM_ERROR_NOACCESS) code = cm_Lookup(dscp, NetName, CM_FLAG_CASEFOLD | CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); if (scp == NULL && code != CM_ERROR_NOACCESS) { /* Try a submount */ code = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\OpenAFS\\Client\\Submounts", 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { cblen = sizeof(pathstr); code = RegQueryValueExW(parmKey, NetName, NULL, NULL, (BYTE *) pathstr, &cblen); if (code != ERROR_SUCCESS) cblen = 0; RegCloseKey (parmKey); } else { cblen = 0; } if (cblen) { code = cm_NameI(dscp, pathstr, CM_FLAG_FOLLOW, userp, NULL, &req, &scp); if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_NOSUCHPATH || code == CM_ERROR_BPLUS_NOMATCH) code = cm_NameI(dscp, pathstr, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, &req, &scp); } else { code = CM_ERROR_NOSUCHPATH; } } } if (scp) { /* Allocate the memory for the response */ switch (Level) { case 2: InfoStruct->ShareInfo2 = MIDL_user_allocate(sizeof(SHARE_INFO_2)); break; case 1: InfoStruct->ShareInfo1 = MIDL_user_allocate(sizeof(SHARE_INFO_1)); break; case 0: InfoStruct->ShareInfo0 = MIDL_user_allocate(sizeof(SHARE_INFO_0)); break; case 501: case 502: case 503: case 1004: case 1005: case 1006: default: cm_ReleaseSCache(scp); return HRESULT_FROM_WIN32(ERROR_INVALID_LEVEL); } if (InfoStruct->ShareInfo0 == NULL) { cm_ReleaseSCache(scp); return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } switch (Level) { case 2: /* for share level security */ InfoStruct->ShareInfo2->shi2_permissions = 0; InfoStruct->ShareInfo2->shi2_max_uses = -1; InfoStruct->ShareInfo2->shi2_current_uses = 0; InfoStruct->ShareInfo2->shi2_path = NetrIntGenerateSharePath(ServerName, &scp->fid); /* must be the empty string */ InfoStruct->ShareInfo2->shi2_passwd = wcsdup(L""); AFS_FALLTHROUGH; case 1: InfoStruct->ShareInfo1->shi1_type = STYPE_DISKTREE; InfoStruct->ShareInfo1->shi1_remark = NetrIntGenerateShareRemark(scp, &scp->fid); AFS_FALLTHROUGH; case 0: /* Canonicalized version of NetName parameter */ InfoStruct->ShareInfo0->shi0_netname = wcsdup(NetName); break; case 501: case 502: case 503: case 1004: case 1005: case 1006: default: status = ERROR_INVALID_LEVEL; } cm_ReleaseSCache(scp); } else { /* * The requested object does not exist. * Return the correct NERR or Win32 Error. */ smb_MapWin32Error(code, &status); switch (status) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_INVALID_NAME: case ERROR_BAD_NETPATH: status = NERR_NetNameNotFound; break; } } return status; } NET_API_STATUS NetrShareSetInfo( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *NetName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPSHARE_INFO ShareInfo, /* [unique][out][in] */ DWORD *ParmErr) { osi_Log0(afsd_logp, "NetrShareSetInfo not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareDel( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *NetName, /* [in] */ DWORD Reserved) { osi_Log0(afsd_logp, "NetrShareDel not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareDelSticky( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *NetName, /* [in] */ DWORD Reserved) { osi_Log0(afsd_logp, "NetrShareDelSticky not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareCheck( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *Device, /* [out] */ DWORD *Type) { osi_Log0(afsd_logp, "NetrShareCheck not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerGetInfo( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][out] */ LPSERVER_INFO InfoStruct) { wchar_t *s; osi_Log1(afsd_logp, "NetrServerGetInfo level %u", Level); /* * How much space do we need and do we have that much room? * For now, just assume we can return everything in one shot * because the reality is that in this function call we do * not know the max size of the RPC response. */ switch (Level) { case 103: InfoStruct->ServerInfo103 = MIDL_user_allocate(sizeof(SERVER_INFO_103)); break; case 102: InfoStruct->ServerInfo102 = MIDL_user_allocate(sizeof(SERVER_INFO_102)); break; case 101: InfoStruct->ServerInfo101 = MIDL_user_allocate(sizeof(SERVER_INFO_101)); break; case 100: InfoStruct->ServerInfo100 = MIDL_user_allocate(sizeof(SERVER_INFO_100)); break; } if (InfoStruct->ServerInfo100 == NULL) { return ERROR_NOT_ENOUGH_MEMORY; } /* * Remove any leading slashes since they are not part of the * server name. */ for ( s=ServerName; *s == '\\' || *s == '/'; s++); switch (Level) { case 103: InfoStruct->ServerInfo103->sv103_capabilities = 0; AFS_FALLTHROUGH; case 102: InfoStruct->ServerInfo102->sv102_users = 0xFFFFFFFF; InfoStruct->ServerInfo102->sv102_disc = SV_NODISC; InfoStruct->ServerInfo102->sv102_hidden = SV_HIDDEN; InfoStruct->ServerInfo102->sv102_announce = 65535; InfoStruct->ServerInfo102->sv102_anndelta = 0; InfoStruct->ServerInfo102->sv102_licenses = 0; InfoStruct->ServerInfo102->sv102_userpath = wcsdup(L"C:\\"); AFS_FALLTHROUGH; case 101: InfoStruct->ServerInfo101->sv101_version_major = AFSPRODUCT_VERSION_MAJOR; InfoStruct->ServerInfo101->sv101_version_minor = AFSPRODUCT_VERSION_MINOR; InfoStruct->ServerInfo101->sv101_type = SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_SERVER_UNIX; InfoStruct->ServerInfo101->sv101_comment = wcsdup(wAFSVersion); AFS_FALLTHROUGH; case 100: InfoStruct->ServerInfo100->sv100_platform_id = SV_PLATFORM_ID_AFS; /* The Netbios Name */ InfoStruct->ServerInfo100->sv100_name = _wcsupr(wcsdup(s)); return 0; case 502: case 503: case 599: case 1005: case 1107: case 1010: case 1016: case 1017: case 1018: case 1501: case 1502: case 1503: case 1506: case 1510: case 1511: case 1512: case 1513: case 1514: case 1515: case 1516: case 1518: case 1523: case 1528: case 1529: case 1530: case 1533: case 1534: case 1535: case 1536: case 1538: case 1539: case 1540: case 1541: case 1542: case 1543: case 1544: case 1545: case 1546: case 1547: case 1548: case 1549: case 1550: case 1552: case 1553: case 1554: case 1555: case 1556: default: return ERROR_INVALID_LEVEL; } return 0; } NET_API_STATUS NetrServerSetInfo( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPSERVER_INFO ServerInfo, /* [unique][out][in] */ DWORD *ParmErr) { osi_Log0(afsd_logp, "NetrServerSetInfo not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerDiskEnum( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [out][in] */ DISK_ENUM_CONTAINER *DiskInfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ DWORD *TotalEntries, /* [unique][out][in] */ DWORD *ResumeHandle) { osi_Log0(afsd_logp, "NetrServerDiskEnum not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerStatisticsGet( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][string][in] */ WCHAR *Service, /* [in] */ DWORD Level, /* [in] */ DWORD Options, /* [out] */ LPSTAT_SERVER_0 *InfoStruct) { osi_Log0(afsd_logp, "NetrServerStatisticsGet not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerTransportAdd( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer) { osi_Log0(afsd_logp, "NetrServerTransportAdd not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerTransportEnum( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [out][in] */ LPSERVER_XPORT_ENUM_STRUCT InfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ DWORD *TotalEntries, /* [unique][out][in] */ DWORD *ResumeHandle) { osi_Log0(afsd_logp, "NetrServerTransportEnum not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerTransportDel( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [in] */ LPSERVER_TRANSPORT_INFO_0 Buffer) { osi_Log0(afsd_logp, "NetrServerTransportDel not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrRemoteTOD( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [out] */ LPTIME_OF_DAY_INFO *BufferPtr) { osi_Log0(afsd_logp, "NetrRemoteTOD not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetprPathType( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *PathName, /* [out] */ DWORD *PathType, /* [in] */ DWORD Flags) { osi_Log0(afsd_logp, "NetprPathType not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetprPathCanonicalize( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *PathName, /* [size_is][out] */ unsigned char *Outbuf, /* [range][in] */ DWORD OutbufLen, /* [string][in] */ WCHAR *Prefix, /* [out][in] */ DWORD *PathType, /* [in] */ DWORD Flags) { osi_Log0(afsd_logp, "NetprPathCanonicalize not supported"); return ERROR_NOT_SUPPORTED; } long NetprPathCompare( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *PathName1, /* [string][in] */ WCHAR *PathName2, /* [in] */ DWORD PathType, /* [in] */ DWORD Flags) { osi_Log0(afsd_logp, "NetprPathCompare not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetprNameValidate( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *Name, /* [in] */ DWORD NameType, /* [in] */ DWORD Flags) { osi_Log0(afsd_logp, "NetprNameValidate not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetprNameCanonicalize( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *Name, /* [size_is][out] */ WCHAR *Outbuf, /* [range][in] */ DWORD OutbufLen, /* [in] */ DWORD NameType, /* [in] */ DWORD Flags) { osi_Log0(afsd_logp, "NetprNameCanonicalize not supported"); return ERROR_NOT_SUPPORTED; } long NetprNameCompare( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *Name1, /* [string][in] */ WCHAR *Name2, /* [in] */ DWORD NameType, /* [in] */ DWORD Flags) { osi_Log0(afsd_logp, "NetprNameCompare not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareEnumSticky( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [out][in] */ LPSHARE_ENUM_STRUCT InfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ DWORD *TotalEntries, /* [unique][out][in] */ DWORD *ResumeHandle) { osi_Log0(afsd_logp, "NetrShareEnumSticky not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareDelStart( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *NetName, /* [in] */ DWORD Reserved, /* [out] */ PSHARE_DEL_HANDLE ContextHandle) { osi_Log0(afsd_logp, "NetrShareDelStart not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareDelCommit( /* [out][in] */ PSHARE_DEL_HANDLE ContextHandle) { osi_Log0(afsd_logp, "NetrShareDelCommit not supported"); return ERROR_NOT_SUPPORTED; } DWORD NetrpGetFileSecurity( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][string][in] */ WCHAR *ShareName, /* [string][in] */ WCHAR *lpFileName, /* [in] */ SECURITY_INFORMATION RequestedInformation, /* [out] */ PADT_SECURITY_DESCRIPTOR *SecurityDescriptor) { osi_Log0(afsd_logp, "NetprGetFileSecurity not supported"); return ERROR_NOT_SUPPORTED; } DWORD NetrpSetFileSecurity( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][string][in] */ WCHAR *ShareName, /* [string][in] */ WCHAR *lpFileName, /* [in] */ SECURITY_INFORMATION SecurityInformation, /* [in] */ PADT_SECURITY_DESCRIPTOR SecurityDescriptor) { osi_Log0(afsd_logp, "NetprSetFileSecurity not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerTransportAddEx( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPTRANSPORT_INFO Buffer) { osi_Log0(afsd_logp, "NetrServerTransportAddEx not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsGetVersion( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [out] */ DWORD *Version) { osi_Log0(afsd_logp, "NetrDfsGetVersion not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsCreateLocalPartition( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *ShareName, /* [in] */ GUID *EntryUid, /* [string][in] */ WCHAR *EntryPrefix, /* [string][in] */ WCHAR *ShortName, /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo, /* [in] */ int Force) { osi_Log0(afsd_logp, "NetrDfsCreateLocalPartition not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsDeleteLocalPartition( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ GUID *Uid, /* [string][in] */ WCHAR *Prefix) { osi_Log0(afsd_logp, "NetrDfsDeleteLocalPartition not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsSetLocalVolumeState( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ GUID *Uid, /* [string][in] */ WCHAR *Prefix, /* [in] */ unsigned long State) { osi_Log0(afsd_logp, "NetrDfsSetLocalVolumeState not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsCreateExitPoint( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ GUID *Uid, /* [string][in] */ WCHAR *Prefix, /* [in] */ unsigned long Type, /* [range][in] */ DWORD ShortPrefixLen, /* [size_is][string][out] */ WCHAR *ShortPrefix) { osi_Log0(afsd_logp, "NetrDfsCreateExitPoint not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsDeleteExitPoint( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ GUID *Uid, /* [string][in] */ WCHAR *Prefix, /* [in] */ unsigned long Type) { osi_Log0(afsd_logp, "NetrDfsDeleteExitPoint not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsModifyPrefix( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ GUID *Uid, /* [string][in] */ WCHAR *Prefix) { osi_Log0(afsd_logp, "NetrDfsModifyPrefix not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsFixLocalVolume( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [string][in] */ WCHAR *VolumeName, /* [in] */ unsigned long EntryType, /* [in] */ unsigned long ServiceType, /* [string][in] */ WCHAR *StgId, /* [in] */ GUID *EntryUid, /* [string][in] */ WCHAR *EntryPrefix, /* [in] */ LPNET_DFS_ENTRY_ID_CONTAINER RelationInfo, /* [in] */ unsigned long CreateDisposition) { osi_Log0(afsd_logp, "NetrDfsFixLocalVolume not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrDfsManagerReportSiteInfo( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [unique][out][in] */ LPDFS_SITELIST_INFO *ppSiteInfo) { osi_Log0(afsd_logp, "NetrDfsManagerReportSiteInfo not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerTransportDelEx( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPTRANSPORT_INFO Buffer) { osi_Log0(afsd_logp, "NetrServerTransportDelEx not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerAliasAdd( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct) { osi_Log0(afsd_logp, "NetrServerAliasAdd not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerAliasEnum( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [out][in] */ LPSERVER_ALIAS_ENUM_STRUCT InfoStruct, /* [in] */ DWORD PreferedMaximumLength, /* [out] */ LPDWORD TotalEntries, /* [unique][out][in] */ LPDWORD ResumeHandle) { osi_Log0(afsd_logp, "NetrServerAliasEnum not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrServerAliasDel( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPSERVER_ALIAS_INFO InfoStruct) { osi_Log0(afsd_logp, "NetrServerAliasDel not supported"); return ERROR_NOT_SUPPORTED; } NET_API_STATUS NetrShareDelEx( /* [unique][string][in] */ SRVSVC_HANDLE ServerName, /* [in] */ DWORD Level, /* [switch_is][in] */ LPSHARE_INFO ShareInfo) { osi_Log0(afsd_logp, "NetrShareDelEx not supported"); return ERROR_NOT_SUPPORTED; } void __RPC_USER SHARE_DEL_HANDLE_rundown( SHARE_DEL_HANDLE h) { } /* [nocode] */ void Opnum0NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum1NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum2NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum5NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum6NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum7NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum29NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum42NotUsedOnWire( /* [in] */ handle_t IDL_handle) { } /* [nocode] */ void Opnum47NotUsedOnWire( /* [in] */ handle_t IDL_handle) { }