在现代IT环境中,系统管理员经常需要在不同的机器之间复制文件共享权限。这可能是由于备份恢复、迁移到新服务器或者权限更新等原因。本文介绍的工具能够实现这一功能,它利用了NetShare API来枚举源机器上的共享资源,并将这些资源的权限应用到目标机器上。
NetShare API是一组Windows API,用于管理和操作网络共享。这些API包括但不限于NetShareEnum、NetShareAdd和NetShareSetInfo。
NetShareEnum函数用于枚举指定计算机上的共享资源。它返回一个共享信息结构的数组,每个结构包含了共享资源的详细信息,如共享名、路径、权限等。
NetShareAdd函数用于在目标计算机上创建一个新的共享资源。它需要指定共享名、路径和共享信息结构。
NetShareSetInfo函数用于修改已存在的共享资源的属性。如果共享资源已经存在,可以使用这个函数来更新它的信息。
NetApiBufferFree函数用于清理NetShareEnum函数分配的内存。
工具的主要逻辑如下:
do {
// 枚举共享资源
res = NetShareEnum(lpszMachine1, 502, (LPBYTE *) &BufPtr, -1, &er, &tr, &resume);
if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) {
// 保存共享信息结构
p = BufPtr;
for (i = 1; i <= er; i++) {
// 检查是否是有效的安全描述符
if (IsValidSecurityDescriptor(p->shi502_security_descriptor) != 0) {
if (iShow == SHOWNETNAME) {
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)p->shi502_netname, MAX_PATH, szBuffer, MAX_PATH, NULL, NULL);
} else {
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)p->shi502_path, MAX_PATH, szBuffer, MAX_PATH, NULL, NULL);
}
// 打印一些点
printf("%s ", szBuffer);
// 是否询问用户
if (bPrompt == TRUE) {
char ch = getch();
if (ch == 'n' || ch == 'N') {
for (int k = 0; k < abs(60 - strlen(szBuffer)) && k < 60; k++) printf(".");
printf("SKIPPED\n");
p++;
continue;
}
}
for (int k = 0; k < abs(60 - strlen(szBuffer)) && k < 60; k++) printf(".");
// 是否需要创建目录
if (TRUE == bCreateDir) {
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)p->shi502_path, MAX_PATH, szPath, MAX_PATH, NULL, NULL);
if (_chdir(szPath) != 0) {
// 尝试创建目录
_mkdir(szPath);
}
}
// 是否需要设置max_uses成员
if (bSetMax == TRUE) p->shi502_max_uses = max_use;
// 尝试添加共享
res = NetShareAdd(lpszMachine2, 502, (LPBYTE)p, NULL);
switch (res) {
case NERR_Success:
printf("SUCCESS\n");
break;
case NERR_DuplicateShare:
// 如果文件夹已经共享,只需设置共享权限
res2 = NetShareSetInfo(lpszMachine2, p->shi502_netname, 502, (LPBYTE)p, NULL);
if (NERR_Success != res2) {
printf("FAILED(#%d)\n", res2);
bSuccess = FALSE;
} else {
printf("SUCCESS\n");
}
break;
default:
printf("FAILED(#%d)\n", res);
bSuccess = FALSE;
}
} else {
if (iShow == SHOWPATH) {
if (lstrlen(p->shi502_path) > 0) {
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)p->shi502_path, MAX_PATH, szBuffer, MAX_PATH, NULL, NULL);
printf("%s ", szBuffer);
for (int k = 0; k < abs(60 - strlen(szBuffer)) && k < 60; k++) printf(".");
printf("INVALID SD\n");
}
} else {
if (lstrlen(p->shi502_netname) > 0) {
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)p->shi502_netname, MAX_PATH, szBuffer, MAX_PATH, NULL, NULL);
printf("%s ", szBuffer);
for (int k = 0; k < abs(60 - strlen(szBuffer)) && k < 60; k++) printf(".");
printf("INVALID SD\n");
}
}
}
p++;
}
if (NetApiBufferFree(BufPtr) != NERR_Success) {
printf("Unable to do cleanup.\n");
}
} else {
wprintf(L"(#%ld) No shared devices\\directories found on computer %s, or access denied.\n", res, lpszMachine1);
bSuccess = FALSE;
}
} while (res == ERROR_MORE_DATA);