specifying password using NetShareEnum

S

Siddharth Jain

hello

I am trying to enumerate the shared folders on a server using the
NetShareEnum function.
Now, when the server has a password set to access the shared folders,
the function returns system error code 5 (access denied).

However, if I know the password to access the shares, how can I specify
that in my program?

The basic skeleton of my prog is as follows:

StructLayout( LayoutKind.Sequential )]
public struct SHARE_INFO_0
{
[MarshalAs( UnmanagedType.LPWStr )] public String shi0_netname;
}
[DllImport("Netapi32.dll")]
public static extern int NetShareEnum([MarshalAs(UnmanagedType.LPWStr)]

string servername,
Int32 level,
out IntPtr bufptr,
Int32 prefmaxlen,
[MarshalAs(UnmanagedType.LPArray)] Int32[] entriesread,
[MarshalAs(UnmanagedType.LPArray)] Int32[] totalentries,
[MarshalAs(UnmanagedType.LPArray)] Int32[] resume_handle
);

[DllImport("Netapi32.dll")]
public static extern int NetApiBufferFree(long lpBuffer);

public static string[] GetShares(string server)
{
IntPtr buf = new IntPtr(0);
Int32[] dwEntriesRead = new Int32[1];
dwEntriesRead[0] = 0;
Int32[] dwTotalEntries = new Int32[1];
dwTotalEntries[0] = 0;
Int32[] dwResumeHandle = new Int32[1];
dwResumeHandle[0] = 0;
Int32 success = 0;
string[] shares = new string[0];
success = NetShareEnum(server, 0, out buf, -1, dwEntriesRead,
dwTotalEntries, dwResumeHandle);

if(dwEntriesRead[0] > 0)
{
SHARE_INFO_0[] s0 = new SHARE_INFO_0[dwEntriesRead[0]];
shares = new string[dwEntriesRead[0]];
for(int i = 0; i < dwEntriesRead[0]; i++)
{

s0 = (SHARE_INFO_0) Marshal.PtrToStructure(buf,
typeof(SHARE_INFO_0));
shares = s0.shi0_netname;
buf = (IntPtr)((long) buf + Marshal.SizeOf(s0[0]));
}
NetApiBufferFree((long) buf);
}
return shares;
}
 
W

Willy Denoyette [MVP]

1. You can't specify user credentials when using the Net API's, please read
the WIN32 API description carefully (especially the remarks and the
Security Requirements for the Network Management Functions. )
You have to impersonate or you need to create a session with the server
using an administrative share (net use \\server\IPC$ ....)

2. Your NetShareEnum declaration is incorrect, the last 3 arguments should
be

out int entriesread,
out int totalentries,
ref IntPtr resume_handle

3. You better stay away from WIN32 API calls if managed solutions are
available, System.Management or System.DirectoryServices are built to allow
you to perform network management tasks using managed code.

Here is a sample using System.DirectoryServices and ADSI (through the
imported activeds.tlb)

using System;
using System.DirectoryServices;
using activeds; // this refers to the namespace of the imported activeds.tlb
(set reference to %windir%\system32\activeds.tlb)
// List all File shares on a system only for W2K and higher
class Tester {
public static void Main() {
// SERVER: name of the server you want to enumerate
// userName: valid user on server
// pwd: his password
using(DirectoryEntry container = new
DirectoryEntry("WinNT://SERVER/LanmanServer", "userName", "pwd",
AuthenticationTypes.ServerBind))
{
foreach(IADsFileShare share in container.NativeObject as IADsContainer)
{
Console.WriteLine("{0} \t{1} \t{2}", share.Name, share.Path,
share.Description);
}
}
}
}

And here is the same using System.Management (and WMI). Note that for this
to work properly you need to grant remote access privileges the the account
connecting to WMI o the remote system.

....
ManagementPath path = new ManagementPath();
path.Server = "SERVER"; // name of the remote system
path.NamespacePath = @"root\CIMV2";
//Connect to the remote computer
ConnectionOptions co = new ConnectionOptions();
// Using valid credentials on SERVER
co.Username = "user";
co.Password = "pwd";
ManagementScope ms = new ManagementScope(path, co);
path.RelativePath ="Win32_Share";
ManagementClass shares = null;
using(shares = new ManagementClass(ms,path,null))
{
ManagementObjectCollection moc = shares.GetInstances();
foreach(ManagementObject mo in moc)
// dump local drive and UNC path
Console.WriteLine("{0} - {1} - {2}",mo["Name"],mo["Path"],
mo["Description"]);
}
Willy.

Siddharth Jain said:
hello

I am trying to enumerate the shared folders on a server using the
NetShareEnum function.
Now, when the server has a password set to access the shared folders,
the function returns system error code 5 (access denied).

However, if I know the password to access the shares, how can I specify
that in my program?

The basic skeleton of my prog is as follows:

StructLayout( LayoutKind.Sequential )]
public struct SHARE_INFO_0
{
[MarshalAs( UnmanagedType.LPWStr )] public String shi0_netname;
}
[DllImport("Netapi32.dll")]
public static extern int NetShareEnum([MarshalAs(UnmanagedType.LPWStr)]

string servername,
Int32 level,
out IntPtr bufptr,
Int32 prefmaxlen,
[MarshalAs(UnmanagedType.LPArray)] Int32[] entriesread,
[MarshalAs(UnmanagedType.LPArray)] Int32[] totalentries,
[MarshalAs(UnmanagedType.LPArray)] Int32[] resume_handle
);

[DllImport("Netapi32.dll")]
public static extern int NetApiBufferFree(long lpBuffer);

public static string[] GetShares(string server)
{
IntPtr buf = new IntPtr(0);
Int32[] dwEntriesRead = new Int32[1];
dwEntriesRead[0] = 0;
Int32[] dwTotalEntries = new Int32[1];
dwTotalEntries[0] = 0;
Int32[] dwResumeHandle = new Int32[1];
dwResumeHandle[0] = 0;
Int32 success = 0;
string[] shares = new string[0];
success = NetShareEnum(server, 0, out buf, -1, dwEntriesRead,
dwTotalEntries, dwResumeHandle);

if(dwEntriesRead[0] > 0)
{
SHARE_INFO_0[] s0 = new SHARE_INFO_0[dwEntriesRead[0]];
shares = new string[dwEntriesRead[0]];
for(int i = 0; i < dwEntriesRead[0]; i++)
{

s0 = (SHARE_INFO_0) Marshal.PtrToStructure(buf,
typeof(SHARE_INFO_0));
shares = s0.shi0_netname;
buf = (IntPtr)((long) buf + Marshal.SizeOf(s0[0]));
}
NetApiBufferFree((long) buf);
}
return shares;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top