public DfsReferral() { // Server // Share // Path relative to tree from which this referral was thrown Next = this; }
/// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> public virtual DfsReferral GetReferral(SmbTransport trans, string domain, string root, string path, NtlmPasswordAuthentication auth) { if (Disabled) { return(null); } try { string p = "\\" + domain + "\\" + root; if (path != null) { p += path; } DfsReferral dr = trans.GetDfsReferrals(auth, p, 0); if (dr != null) { return(dr); } } catch (IOException ioe) { if (Log.Level >= 4) { Runtime.PrintStackTrace(ioe, Log); } if (StrictView && ioe is SmbAuthException) { throw (SmbAuthException)ioe; } } return(null); }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> internal virtual void CheckStatus(ServerMessageBlock req, ServerMessageBlock resp ) { resp.ErrorCode = SmbException.GetStatusByCode(resp.ErrorCode); switch (resp.ErrorCode) { case NtStatus.NtStatusOk: { break; } case NtStatus.NtStatusAccessDenied: case NtStatus.NtStatusWrongPassword: case NtStatus.NtStatusLogonFailure: case NtStatus.NtStatusAccountRestriction: case NtStatus.NtStatusInvalidLogonHours: case NtStatus.NtStatusInvalidWorkstation: case NtStatus.NtStatusPasswordExpired: case NtStatus.NtStatusAccountDisabled: case NtStatus.NtStatusAccountLockedOut: case NtStatus.NtStatusTrustedDomainFailure: { throw new SmbAuthException(resp.ErrorCode); } case NtStatus.NtStatusPathNotCovered: { if (req.Auth == null) { throw new SmbException(resp.ErrorCode, null); } DfsReferral dr = GetDfsReferrals(req.Auth, req.Path, 1); if (dr == null) { throw new SmbException(resp.ErrorCode, null); } SmbFile.Dfs.Insert(req.Path, dr); throw dr; } case unchecked ((int)(0x80000005)): { break; } case NtStatus.NtStatusMoreProcessingRequired: { break; } default: { throw new SmbException(resp.ErrorCode, null); } } if (resp.VerifyFailed) { throw new SmbException("Signature verification failed."); } }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> internal virtual DfsReferral GetDfsReferrals(NtlmPasswordAuthentication auth, string path, int rn) { SmbTree ipc = GetSmbSession(auth).GetSmbTree("IPC$", null); Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse(); ipc.Send(new Trans2GetDfsReferral(path), resp); if (resp.NumReferrals == 0) { return(null); } if (rn == 0 || resp.NumReferrals < rn) { rn = resp.NumReferrals; } DfsReferral dr = new DfsReferral(); string[] arr = new string[4]; long expiration = Runtime.CurrentTimeMillis() + Dfs.Ttl * 1000; int di = 0; for (;;) { dr.ResolveHashes = auth.HashesExternal; dr.Ttl = resp.Referrals[di].Ttl; dr.Expiration = expiration; if (path.Equals(string.Empty)) { dr.Server = Runtime.Substring(resp.Referrals[di].Path, 1).ToLower(); } else { DfsPathSplit(resp.Referrals[di].Node, arr); dr.Server = arr[1]; dr.Share = arr[2]; dr.Path = arr[3]; } dr.PathConsumed = resp.PathConsumed; di++; if (di == rn) { break; } dr.Append(new DfsReferral()); dr = dr.Next; } return(dr.Next); }
/// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> public virtual Hashtable GetTrustedDomains(NtlmPasswordAuthentication auth) { if (Disabled || auth.Domain == "?") { return(null); } if (Domains != null && Runtime.CurrentTimeMillis() > Domains.Expiration) { Domains = null; } if (Domains != null) { return(Domains.Map); } try { UniAddress addr = UniAddress.GetByName(auth.Domain, true); SmbTransport trans = SmbTransport.GetSmbTransport(addr, 0); CacheEntry entry = new CacheEntry(Ttl * 10L); DfsReferral dr = trans.GetDfsReferrals(auth, string.Empty, 0); if (dr != null) { DfsReferral start = dr; do { string domain = dr.Server.ToLower(); entry.Map.Put(domain, new Hashtable()); dr = dr.Next; }while (dr != start); Domains = entry; return(Domains.Map); } } catch (IOException ioe) { if (Log.Level >= 3) { Runtime.PrintStackTrace(ioe, Log); } if (StrictView && ioe is SmbAuthException) { throw (SmbAuthException)ioe; } } return(null); }
/// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> public virtual SmbTransport GetDc(string domain, NtlmPasswordAuthentication auth) { if (Disabled) { return(null); } try { UniAddress addr = UniAddress.GetByName(domain, true); SmbTransport trans = SmbTransport.GetSmbTransport(addr, 0); DfsReferral dr = trans.GetDfsReferrals(auth, "\\" + domain, 1); if (dr != null) { DfsReferral start = dr; IOException e = null; do { try { addr = UniAddress.GetByName(dr.Server); return(SmbTransport.GetSmbTransport(addr, 0)); } catch (IOException ioe) { e = ioe; } dr = dr.Next; }while (dr != start); throw e; } } catch (IOException ioe) { if (Log.Level >= 3) { Runtime.PrintStackTrace(ioe, Log); } if (StrictView && ioe is SmbAuthException) { throw (SmbAuthException)ioe; } } return(null); }
internal virtual void Insert(string path, DfsReferral dr) { lock (this) { int s1; int s2; string server; string share; string key; if (Disabled) { return; } s1 = path.IndexOf('\\', 1); s2 = path.IndexOf('\\', s1 + 1); server = Runtime.Substring(path, 1, s1); share = Runtime.Substring(path, s1 + 1, s2); key = Runtime.Substring(path, 0, dr.PathConsumed).ToLower(); int ki = key.Length; while (ki > 1 && key[ki - 1] == '\\') { ki--; } if (ki < key.Length) { key = Runtime.Substring(key, 0, ki); } dr.PathConsumed -= 1 + server.Length + 1 + share.Length; if (Referrals != null && (Runtime.CurrentTimeMillis() + 10000) > Referrals.Expiration) { Referrals = null; } if (Referrals == null) { Referrals = new CacheEntry(0); } Referrals.Map.Put(key, dr); } }
internal virtual void Append(DfsReferral dr) { dr.Next = Next; Next = dr; }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> internal virtual void ResolveDfs(ServerMessageBlock request) { if (!_enableDfs) { Connect0(); return; } if (request is SmbComClose) { return; } Connect0(); DfsReferral dr = Dfs.Resolve(Tree.Session.transport.TconHostName, Tree.Share, Unc , Auth); if (dr != null) { string service = null; if (request != null) { switch (request.Command) { case ServerMessageBlock.SmbComTransaction: case ServerMessageBlock.SmbComTransaction2: { switch (((SmbComTransaction)request).SubCommand & 0xFF) { case SmbComTransaction.Trans2GetDfsReferral: { break; } default: { service = "A:"; break; } } break; } default: { service = "A:"; break; } } } DfsReferral start = dr; SmbException se = null; do { try { if (Log.Level >= 2) { Log.WriteLine("DFS redirect: " + dr); } UniAddress addr = UniAddress.GetByName(dr.Server); SmbTransport trans = SmbTransport.GetSmbTransport(addr, Url.Port); trans.Connect(); Tree = trans.GetSmbSession(Auth).GetSmbTree(dr.Share, service); if (dr != start && dr.Key != null) { dr.Map.Put(dr.Key, dr); } se = null; break; } catch (IOException ioe) { if (ioe is SmbException) { se = (SmbException)ioe; } else { se = new SmbException(dr.Server, ioe); } } dr = dr.Next; } while (dr != start); if (se != null) { throw se; } if (Log.Level >= 3) { Log.WriteLine(dr); } _dfsReferral = dr; if (dr.PathConsumed < 0) { dr.PathConsumed = 0; } else { if (dr.PathConsumed > Unc.Length) { dr.PathConsumed = Unc.Length; } } string dunc = Runtime.Substring(Unc, dr.PathConsumed); if (dunc.Equals(string.Empty)) { dunc = "\\"; } if (!dr.Path.Equals(string.Empty)) { dunc = "\\" + dr.Path + dunc; } Unc = dunc; if (request != null && request.Path != null && request.Path.EndsWith("\\") && dunc .EndsWith("\\") == false) { dunc += "\\"; } if (request != null) { request.Path = dunc; request.Flags2 |= SmbConstants.Flags2ResolvePathsInDfs; } } else { if (Tree.InDomainDfs && !(request is NtTransQuerySecurityDesc) && !(request is SmbComClose ) && !(request is SmbComFindClose2)) { throw new SmbException(NtStatus.NtStatusNotFound, false); } if (request != null) { request.Flags2 &= ~SmbConstants.Flags2ResolvePathsInDfs; } } }
/// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> /*internal SmbFile(Jcifs.Smb.SmbFile context, string name, int type, int attributes , long createTime, long lastModified, long size) : this(context.IsWorkgroup0() ? new Uri(null, "smb://" + name + "/") : new Uri(context.url, name + ((attributes & ATTR_DIRECTORY) > 0 ? "/" : string.Empty)))*/ internal SmbFile(SmbFile context, string name, int type, int attributes , long createTime, long lastModified, long size) : this(context.IsWorkgroup0() ? new Uri("smb://" + name + "/") : new Uri(context.Url.AbsoluteUri + name + ((attributes & AttrDirectory) > 0 ? "/" : string.Empty))) { Auth = context.Auth; if (context._share != null) { Tree = context.Tree; _dfsReferral = context._dfsReferral; } int last = name.Length - 1; if (name[last] == '/') { name = Runtime.Substring(name, 0, last); } if (context._share == null) { Unc = "\\"; } else { if (context.Unc.Equals("\\")) { Unc = '\\' + name; } else { Unc = context.Unc + '\\' + name; } } if (!context.IsWorkgroup0()) { Addresses = context.Addresses; } this._enableDfs = context.EnableDfs; this.Type = type; this._attributes = attributes; this._createTime = createTime; this._lastModified = lastModified; this._size = size; _isExists = true; _attrExpiration = _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; }
/// <summary> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. /// </summary> /// <remarks> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. The second parameter is a relative path from /// the <code>context</code>. See the description above for examples of /// using the second <code>name</code> parameter. The <tt>shareAccess</tt> /// parameter controls what permissions other clients have when trying /// to access the same file while this instance is still open. This /// value is either <tt>FILE_NO_SHARE</tt> or any combination /// of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>, and /// <tt>FILE_SHARE_DELETE</tt> logically OR'd together. /// </remarks> /// <param name="context">A base <code>SmbFile</code></param> /// <param name="name">A path string relative to the <code>context</code> file path</param> /// <param name="shareAccess">Specifies what access other clients have while this file is open. /// </param> /// <exception cref="System.UriFormatException"> /// If the <code>context</code> and <code>name</code> parameters /// do not follow the prescribed syntax /// </exception> /// <exception cref="UnknownHostException"></exception> public SmbFile(SmbFile context, string name, int shareAccess) : this(context.IsWorkgroup0() ? new Uri("smb://" + name) : new Uri( context.Url.AbsoluteUri + name), context.Auth) { if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != 0) { throw new RuntimeException("Illegal shareAccess parameter"); } if (!context.IsWorkgroup0()) { this.Addresses = context.Addresses; if (context._share != null || context.Tree != null) { Tree = context.Tree; _dfsReferral = context._dfsReferral; } } this._shareAccess = shareAccess; this._enableDfs = context.EnableDfs; }
/// <summary> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. /// </summary> /// <remarks> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. The second parameter is a relative path from /// the <code>parent SmbFile</code>. See the description above for examples /// of using the second <code>name</code> parameter. /// </remarks> /// <param name="context">A base <code>SmbFile</code></param> /// <param name="name">A path string relative to the <code>parent</code> paremeter</param> /// <exception cref="System.UriFormatException"> /// If the <code>parent</code> and <code>child</code> parameters /// do not follow the prescribed syntax /// </exception> /// <exception cref="UnknownHostException">If the server or workgroup of the <tt>context</tt> file cannot be determined /// </exception> public SmbFile(SmbFile context, string name) : this(context.IsWorkgroup0 () ? new Uri("smb://" + name) : new Uri(context.Url.AbsoluteUri + name), context.Auth) { this._enableDfs = context.EnableDfs; if (!context.IsWorkgroup0()) { Addresses = context.Addresses; if (context._share != null) { Tree = context.Tree; _dfsReferral = context._dfsReferral; } } }
/// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> public virtual DfsReferral Resolve(string domain, string root, string path, NtlmPasswordAuthentication auth) { lock (this) { DfsReferral dr = null; long now = Runtime.CurrentTimeMillis(); if (Disabled || root.Equals("IPC$")) { return(null); } Hashtable domains = GetTrustedDomains(auth); if (domains != null) { domain = domain.ToLower(); Hashtable roots = (Hashtable)domains.Get(domain); if (roots != null) { SmbTransport trans = null; root = root.ToLower(); CacheEntry links = (CacheEntry)roots.Get(root); if (links != null && now > links.Expiration) { //Sharpen.Collections.Remove(roots, root); roots.Remove(root); links = null; } if (links == null) { if ((trans = GetDc(domain, auth)) == null) { return(null); } dr = GetReferral(trans, domain, root, path, auth); if (dr != null) { int len = 1 + domain.Length + 1 + root.Length; links = new CacheEntry(0L); DfsReferral tmp = dr; do { if (path == null) { // TODO: fix this //tmp.map = links.map; tmp.Key = "\\"; } tmp.PathConsumed -= len; tmp = tmp.Next; }while (tmp != dr); if (dr.Key != null) { links.Map.Put(dr.Key, dr); } roots.Put(root, links); } else { if (path == null) { roots.Put(root, FalseEntry); } } } else { if (links == FalseEntry) { links = null; } } if (links != null) { string link = "\\"; dr = (DfsReferral)links.Map.Get(link); if (dr != null && now > dr.Expiration) { //Sharpen.Collections.Remove(links.map, link); links.Map.Remove(link); dr = null; } if (dr == null) { if (trans == null) { if ((trans = GetDc(domain, auth)) == null) { return(null); } } dr = GetReferral(trans, domain, root, path, auth); if (dr != null) { dr.PathConsumed -= 1 + domain.Length + 1 + root.Length; dr.Link = link; links.Map.Put(link, dr); } } } } } if (dr == null && path != null) { if (Referrals != null && now > Referrals.Expiration) { Referrals = null; } if (Referrals == null) { Referrals = new CacheEntry(0); } string key = "\\" + domain + "\\" + root; if (path.Equals("\\") == false) { key += path; } key = key.ToLower(); //ListIterator<object> iter = new ListIterator<object>(referrals.map.Keys.GetEnumerator(), 0); foreach (var current in Referrals.Map.Keys) { string _key = (string)current; int klen = _key.Length; bool match = false; if (klen == key.Length) { match = _key.Equals(key); } else { if (klen < key.Length) { match = _key.RegionMatches(false, 0, key, 0, klen) && key[klen] == '\\'; } } if (match) { dr = (DfsReferral)Referrals.Map.Get(_key); } } } return(dr); } }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> internal virtual DfsReferral[] __getDfsReferrals(NtlmPasswordAuthentication auth, string path, int rn) { SmbTree ipc = GetSmbSession(auth).GetSmbTree("IPC$", null); Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse(); ipc.Send(new Trans2GetDfsReferral(path), resp); if (rn == 0 || resp.NumReferrals < rn) { rn = resp.NumReferrals; } DfsReferral[] drs = new DfsReferral[rn]; string[] arr = new string[4]; long expiration = Runtime.CurrentTimeMillis() + Dfs.Ttl * 1000; for (int di = 0; di < drs.Length; di++) { DfsReferral dr = new DfsReferral(); dr.ResolveHashes = auth.HashesExternal; dr.Ttl = resp.Referrals[di].Ttl; dr.Expiration = expiration; if (path.Equals(string.Empty)) { dr.Server = Runtime.Substring(resp.Referrals[di].Path, 1).ToLower(); } else { DfsPathSplit(resp.Referrals[di].Node, arr); dr.Server = arr[1]; dr.Share = arr[2]; dr.Path = arr[3]; } dr.PathConsumed = resp.PathConsumed; drs[di] = dr; } return drs; }