def iterConnectableShares(self): nr = win32wnet.NETRESOURCE() nr.dwScope = RESOURCE_GLOBALNET nr.dwUsage = RESOURCEUSAGE_CONTAINER nr.lpRemoteName = "\\\\" + win32api.GetComputerName() handle = win32wnet.WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, nr) while 1: items = win32wnet.WNetEnumResource(handle, 0) if len(items) == 0: break for item in items: if item.dwDisplayType == RESOURCEDISPLAYTYPE_SHARE: yield item
def Initialize(self, path, silent=False): """リソースの情報を取得し、リストを初期化する。""" self.log.debug("Getting resources list...") self.rootDirectory = path t = misc.Timer() if isinstance( path, list ): # パラメータがリストなら、browsableObjects のリストとして処理刷る(ファイルリストを取得しないでコピーする) self.resources += path return errorCodes.OK # end copy self.resources.clear() if not silent: globalVars.app.say(path[2:]) # 取得対象を構造体にセット rootResource = win32wnet.NETRESOURCE() rootResource.lpRemoteName = path # リソースリストの取得 try: h = win32wnet.WNetOpenEnum(2, 1, 0, rootResource) # 2=RESOURCE_GLOBALNET # 1=RESOURCETYPE_DISK lst = win32wnet.WNetEnumResource(h, 64) # 65以上の指定不可 win32wnet.WNetCloseEnum(h) except win32wnet.error as er: dialog( _("エラー"), _("ネットワーク上のリソース一覧を取得できませんでした(%(error)s)") % {"error": str(er)}) return errorCodes.ACCESS_DENIED for l in lst: ret, shfileinfo = shell.SHGetFileInfo(l.lpRemoteName, 0, shellcon.SHGFI_ICON) s = browsableObjects.NetworkResource() self.log.debug("network resource found and check IP address:" + l.lpRemoteName[2:]) s.Initialize(l.lpRemoteName[len(path) + 1:], l.lpRemoteName, "", shfileinfo[0]) self.resources.append(s) self.log.debug("Network resource list created in %d seconds." % t.elapsed) self.log.debug(str(len(self.resources)) + " resources found.") return errorCodes.OK
def _create_manual_mounts(self): """ on Windows, in order to collect statistics on remote (SMB/NFS) drives, the drive must be mounted as the agent user in the agent context, otherwise the agent can't 'see' the drive. If so configured, attempt to mount desired drives """ if not self._manual_mounts: self.log.debug("No manual mounts") else: self.log.debug("Attempting to create %d mounts: ", len(self._manual_mounts)) for manual_mount in self._manual_mounts: remote_machine = manual_mount.get('host') share = manual_mount.get('share') uname = manual_mount.get('user') pword = manual_mount.get('password') mtype = manual_mount.get('type') mountpoint = manual_mount.get('mountpoint') nr = win32wnet.NETRESOURCE() if not remote_machine or not share: self.log.error( "Invalid configuration. Drive mount requires remote machine and share point" ) continue if mtype and mtype.lower() == "nfs": nr.lpRemoteName = r"{}:{}".format(remote_machine, share) self.log.debug("Attempting NFS mount: %s", nr.lpRemoteName) else: nr.lpRemoteName = r"\\{}\{}".format(remote_machine, share).rstrip('\\') self.log.debug("Attempting SMB mount: %s", nr.lpRemoteName) nr.dwType = 0 nr.lpLocalName = mountpoint try: win32wnet.WNetAddConnection2(nr, pword, uname, 0) self.log.debug("Successfully mounted %s as %s", mountpoint, nr.lpRemoteName) except Exception as e: self.log.error("Failed to mount %s %s", nr.lpRemoteName, str(e)) pass
def TestConnection(): if len(possible_shares) == 0: print("Couldn't find any potential shares to connect to") return localName = findUnusedDriveLetter() + ':' for share in possible_shares: print("Attempting connection of", localName, "to", share.lpRemoteName) try: win32wnet.WNetAddConnection2(share.dwType, localName, share.lpRemoteName) except win32wnet.error as details: print("Couldn't connect: " + details.strerror) continue # Have a connection. try: fname = os.path.join(localName + "\\", os.listdir(localName + "\\")[0]) try: print("Universal name of '%s' is '%s'" % (fname, win32wnet.WNetGetUniversalName(fname))) except win32wnet.error as details: print("Couldn't get universal name of '%s': %s" % (fname, details.strerror)) print("User name for this connection is", win32wnet.WNetGetUser(localName)) finally: win32wnet.WNetCancelConnection2(localName, 0, 0) # and do it again, but this time by using the more modern # NETRESOURCE way. nr = win32wnet.NETRESOURCE() nr.dwType = share.dwType nr.lpLocalName = localName nr.lpRemoteName = share.lpRemoteName win32wnet.WNetAddConnection2(nr) win32wnet.WNetCancelConnection2(localName, 0, 0) # and one more time using WNetAddConnection3 win32wnet.WNetAddConnection3(0, nr) win32wnet.WNetCancelConnection2(localName, 0, 0) # Only do the first share that succeeds. break
def _map_path(self, drive, path, user=None, password=None): if os.path.exists(path): self.log.info("Path: {}. reachable. Mapping to drive".format( path, drive)) try: netres = win32wnet.NETRESOURCE() netres.lpLocalName = drive netres.lpRemoteName = path netres.dwType = win32netcon.RESOURCETYPE_DISK if user: win32wnet.WNetAddConnection2(NetResource=netres, Password=password, UserName=user) else: win32wnet.WNetAddConnection2(NetResource=netres) except: self.log.info("Unexpected error while mapping path") raise # return -1 self.log.info("Mapping Successful") return 1 else: self.log.info("Network Path Unrachable") return -1
def _get_netresource(self, remote_machine): # To connect you have to use the name of the server followed by an optional administrative share. # Administrative shares are hidden network shares created that allow system administrators to have remote access # to every disk volume on a network-connected system. # These shares may not be permanently deleted but may be disabled. # Administrative shares cannot be accessed by users without administrative privileges. # # This page explains how to enable them: https://www.wintips.org/how-to-enable-admin-shares-windows-7/ # # The administrative share can be: # * A disk volume like c$ # * admin$: The folder in which Windows is installed # * fax$: The folder in which faxed pages and cover pages are cached # * ipc$: Area used for interprocess communication and is not part of the file system. # * print$: Virtual folder that contains a representation of the installed printers # * Domain controller shares: Windows creates two domain controller specific shares called sysvol and netlogon # which do not have $ appended to their names. # * Empty string: No admin share specified administrative_share = self.instance.get('admin_share', DEFAULT_SHARE) nr = win32wnet.NETRESOURCE() # Specifies the network resource to connect to. nr.lpRemoteName = r"\\{}\{}".format(remote_machine, administrative_share).rstrip('\\') # The type of network resource to connect to. # # Although this member is required, its information may be ignored by the network service provider. nr.dwType = RESOURCETYPE_ANY # Specifies the name of a local device to redirect, such as "F:" or "LPT1". # If the string is empty, NULL, it connects to the network resource without redirecting a local device. nr.lpLocalName = None return nr
def testNETRESOURCE(self): nr = win32wnet.NETRESOURCE() self._checkItemAttributes(nr, NETRESOURCE_attributes)
def __init__(self, name, init_config, agentConfig, instances, counter_list): AgentCheck.__init__(self, name, init_config, agentConfig, instances) self._countersettypes = {} self._counters = {} self._metrics = {} self._tags = {} try: for instance in instances: key = hash_mutable(instance) cfg_tags = instance.get('tags') if cfg_tags is not None: if not isinstance(cfg_tags, list): self.log.error("Tags must be configured as a list") raise ValueError("Tags must be type list, not %s" % str(type(cfg_tags))) self._tags[key] = list(cfg_tags) remote_machine = None host = instance.get('host') self._metrics[key] = [] if host is not None and host != ".": try: remote_machine = host username = instance.get('username') password = instance.get('password') nr = win32wnet.NETRESOURCE() nr.lpRemoteName = r"\\%s\c$" % remote_machine nr.dwType = 0 nr.lpLocalName = None win32wnet.WNetAddConnection2(nr, password, username, 0) except Exception as e: self.log.error("Failed to make remote connection %s" % str(e)) return # list of the metrics. Each entry is itself an entry, # which is the pdh name, datadog metric name, type, and the # pdh counter object for counterset, inst_name, counter_name, dd_name, mtype in counter_list: m = getattr(self, mtype.lower()) obj = WinPDHCounter(counterset, counter_name, self.log, inst_name, machine_name=remote_machine) entry = [inst_name, dd_name, m, obj] self.log.debug("entry: %s" % str(entry)) self._metrics[key].append(entry) # get any additional metrics in the instance addl_metrics = instance.get('additional_metrics') if addl_metrics is not None: for counterset, inst_name, counter_name, dd_name, mtype in addl_metrics: if inst_name.lower() == "none" or len( inst_name ) == 0 or inst_name == "*" or inst_name.lower( ) == "all": inst_name = None m = getattr(self, mtype.lower()) obj = WinPDHCounter(counterset, counter_name, self.log, inst_name, machine_name=remote_machine) entry = [inst_name, dd_name, m, obj] self.log.debug("additional metric entry: %s" % str(entry)) self._metrics[key].append(entry) except Exception as e: self.log.debug("Exception in PDH init: %s", str(e)) raise
def __init__(self, name, init_config, agentConfig, instances, counter_list): AgentCheck.__init__(self, name, init_config, agentConfig, instances) self._missing_counters = {} self._metrics = {} self._tags = {} key = None try: for instance in instances: key = hash_mutable(instance) cfg_tags = instance.get('tags') if cfg_tags is not None: if not isinstance(cfg_tags, list): self.log.error("Tags must be configured as a list") raise ValueError("Tags must be type list, not %s" % str(type(cfg_tags))) self._tags[key] = list(cfg_tags) remote_machine = None host = instance.get('host') self._metrics[key] = [] if host is not None and host != ".": try: remote_machine = host username = instance.get('username') password = instance.get('password') nr = win32wnet.NETRESOURCE() nr.lpRemoteName = r"\\%s\c$" % remote_machine nr.dwType = 0 nr.lpLocalName = None win32wnet.WNetAddConnection2(nr, password, username, 0) except Exception as e: self.log.error("Failed to make remote connection %s", str(e)) return # counter_data_types allows the precision with which counters are queried # to be configured on a per-metric basis. In the metric instance, precision # should be specified as # counter_data_types: # - iis.httpd_request_method.get,int # - iis.net.bytes_rcvd,float # # the above would query the counter associated with iis.httpd_request_method.get # as an integer (LONG) and iis.net.bytes_rcvd as a double datatypes = {} precisions = instance.get('counter_data_types') if precisions is not None: if not isinstance(precisions, list): self.log.warning( "incorrect type for counter_data_type %s", str(precisions)) else: for p in precisions: k, v = p.split(",") v = v.lower().strip() if v in int_types: self.log.info( "Setting datatype for %s to integer", k) datatypes[k] = DATA_TYPE_INT elif v in double_types: self.log.info( "Setting datatype for %s to double", k) datatypes[k] = DATA_TYPE_DOUBLE else: self.log.warning("Unknown data type %s", str(v)) self._make_counters( key, (counter_list, (datatypes, remote_machine, False, 'entry'))) # get any additional metrics in the instance addl_metrics = instance.get('additional_metrics') if addl_metrics is not None: self._make_counters(key, (addl_metrics, (datatypes, remote_machine, True, 'additional metric entry'))) except Exception as e: self.log.debug("Exception in PDH init: %s", str(e)) raise if key is None or not self._metrics.get(key): raise AttributeError('No valid counters to collect')
def __init__(self, name, init_config, agentConfig, instances, counter_list): AgentCheck.__init__(self, name, init_config, agentConfig, instances) self._countersettypes = {} self._counters = {} self._metrics = {} self._tags = {} key = None try: for instance in instances: key = hash_mutable(instance) cfg_tags = instance.get('tags') if cfg_tags is not None: if not isinstance(cfg_tags, list): self.log.error("Tags must be configured as a list") raise ValueError("Tags must be type list, not %s" % str(type(cfg_tags))) self._tags[key] = list(cfg_tags) remote_machine = None host = instance.get('host') self._metrics[key] = [] if host is not None and host != ".": try: remote_machine = host username = instance.get('username') password = instance.get('password') nr = win32wnet.NETRESOURCE() nr.lpRemoteName = r"\\%s\c$" % remote_machine nr.dwType = 0 nr.lpLocalName = None win32wnet.WNetAddConnection2(nr, password, username, 0) except Exception as e: self.log.error("Failed to make remote connection %s" % str(e)) return # counter_data_types allows the precision with which counters are queried # to be configured on a per-metric basis. In the metric instance, precision # should be specified as # counter_data_types: # - iis.httpd_request_method.get,int # - iis.net.bytes_rcvd,float # # the above would query the counter associated with iis.httpd_request_method.get # as an integer (LONG) and iis.net.bytes_rcvd as a double datatypes = {} precisions = instance.get('counter_data_types') if precisions is not None: if not isinstance(precisions, list): self.log.warning( "incorrect type for counter_data_type %s" % str(precisions)) else: for p in precisions: k, v = p.split(",") v = v.lower().strip() if v in int_types: self.log.info( "Setting datatype for %s to integer" % k) datatypes[k] = DATA_TYPE_INT elif v in double_types: self.log.info( "Setting datatype for %s to double" % k) datatypes[k] = DATA_TYPE_DOUBLE else: self.log.warning("Unknown data type %s" % str(v)) # list of the metrics. Each entry is itself an entry, # which is the pdh name, datadog metric name, type, and the # pdh counter object for counterset, inst_name, counter_name, dd_name, mtype in counter_list: m = getattr(self, mtype.lower()) precision = datatypes.get(dd_name) try: obj = WinPDHCounter(counterset, counter_name, self.log, inst_name, machine_name=remote_machine, precision=precision) except Exception: self.log.warning("Couldn't create counter %s\%s" % (counterset, counter_name)) self.log.warning("Datadog Agent will not report %s" % dd_name) continue entry = [inst_name, dd_name, m, obj] self.log.debug("entry: %s" % str(entry)) self._metrics[key].append(entry) # get any additional metrics in the instance addl_metrics = instance.get('additional_metrics') if addl_metrics is not None: for counterset, inst_name, counter_name, dd_name, mtype in addl_metrics: if (inst_name.lower() == "none" or len(inst_name) == 0 or inst_name == "*" or inst_name.lower() == "all"): inst_name = None m = getattr(self, mtype.lower()) precision = datatypes.get(dd_name) try: obj = WinPDHCounter(counterset, counter_name, self.log, inst_name, machine_name=remote_machine, precision=precision) except Exception: self.log.warning("Couldn't create counter %s\%s" % (counterset, counter_name)) self.log.warning( "Datadog Agent will not report %s" % dd_name) continue entry = [inst_name, dd_name, m, obj] self.log.debug("additional metric entry: %s" % str(entry)) self._metrics[key].append(entry) except Exception as e: self.log.debug("Exception in PDH init: %s", str(e)) raise if key is None or not self._metrics.get(key): raise AttributeError('No valid counters to collect')
try: fname = os.path.join(localName + "\\", os.listdir(localName + "\\")[0]) try: print "Universal name of '%s' is '%s'" % ( fname, win32wnet.WNetGetUniversalName(fname)) except win32wnet.error, details: print "Couldn't get universal name of '%s': %s" % ( fname, details.strerror) print "User name for this connection is", win32wnet.WNetGetUser( localName) finally: win32wnet.WNetCancelConnection2(localName, 0, 0) # and do it again, but this time by using the more modern # NETRESOURCE way. nr = win32wnet.NETRESOURCE() nr.dwType = share.dwType nr.lpLocalName = localName nr.lpRemoteName = share.lpRemoteName win32wnet.WNetAddConnection2(nr) win32wnet.WNetCancelConnection2(localName, 0, 0) # and one more time using WNetAddConnection3 win32wnet.WNetAddConnection3(0, nr) win32wnet.WNetCancelConnection2(localName, 0, 0) # Only do the first share that succeeds. break def TestGetUser():