//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: SymLinkNode.sg // // Note: // using System; using System.Text; using System.Collections; using System.Threading; using Microsoft.SingSharp; using Microsoft.Singularity; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Directory; using Microsoft.Singularity.Security; #if !SINGULARITY_PROCESS namespace Microsoft.Singularity.Directory #else using Microsoft.Singularity; using Microsoft.Singularity.V1.Services; namespace Microsoft.Application.DSP #endif { // There are no access checks on symbolic links. // In order to read a link, traverse access to the parent is sufficient. // Although one might think that read access to the parent would be more // appropriate here, the nature of the DirectoryService protocol allows anyone // traversing a link to find the link value, hence there is no benefit to // making "reading" of a link more strict. public class SymLinkNode : Node { private string symbolicLink; public SymLinkNode(string value, string! name, Node! parent) { symbolicLink = value; base(NodeType.SymLink, name, parent); } /// /// null on success, the service argument if it failed. /// public override ServiceContract.Exp Bind(StringBuilder! p, Principal pr, out bool success, out bool linkFound, out ErrorCode error, out bool reparse, out string link, [Claims] ServiceContract.Exp! service) { Kernel.Waypoint(3500); reparse = true; success = true; linkFound = true; error = ErrorCode.NoError; if (! (p.Length == 0)) link = symbolicLink + SbUtils.PathString(p); else link = symbolicLink; Kernel.Waypoint(3501); return service; } /// /// null on success, the sp argument if it failed. /// public override ServiceProviderContract.Imp Register(StringBuilder! p, Principal pr, [Claims]ServiceProviderContract.Imp! sp, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { // cannot register over an existing name reparse = false; linkFound = false; link = null; error = ErrorCode.AlreadyExists; return sp; } /// /// The endpoint on success, null, if it fails. /// public override ServiceProviderContract.Imp:Start Deregister(StringBuilder! path, Principal pr, DirectoryServiceContract.Exp! ep, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { error = ErrorCode.NotSupported; link = null; linkFound = false; reparse = false; if (!(path.Length == 0) ) { return null; } // cannot be removed return null; } /// /// if true returns length and node type, otherwise error /// public override bool GetAttributes(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link, out long length, out NodeType nodeType ) { Kernel.Waypoint(3700); reparse = true; linkFound = true; length = 0; nodeType = NodeType.SymLink; error = ErrorCode.NoError; // this is a traverse operation. There is more left on the path if (! (p.Length == 0)) { link = symbolicLink + SbUtils.PathString(p); return false; } // stop here reparse = false; link = symbolicLink; Kernel.Waypoint(3701); return true; } /// /// true on success, false, if it fails. /// public override NotifyContract.Imp Notify(StringBuilder! pathSpec, Principal pr, string! pattern, bool sendExisting, out bool linkFound, out ErrorCode error, out bool reparse, out string link, [Claims] NotifyContract.Imp! notifyImp) { // this method should never be called error = ErrorCode.NotSupported; reparse = false; link = symbolicLink; linkFound = true; return notifyImp; } public override FileContract.Imp CreateAndBindFile(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; return null; } public override bool CreateDirectory(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { //DebugStub.Break(); reparse = true; linkFound = true; link = null; error = ErrorCode.NoError; if (! (p.Length == 0) ) link = symbolicLink + SbUtils.PathString(p); else link = symbolicLink ; return false; } public override bool CreateFile(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; return false; } public override bool CreateLink(StringBuilder! p, Principal pr, string! value, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { reparse = true; linkFound = true; error = ErrorCode.NoError; if (! (p.Length == 0) ) link = symbolicLink + SbUtils.PathString(p); else link = symbolicLink ; return false; } public override bool DeleteDirectory(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { reparse = true; linkFound = true; error = ErrorCode.NoError; if (! (p.Length == 0) ) { link = symbolicLink + SbUtils.PathString(p); return false; } link = symbolicLink ; error = ErrorCode.NotDirectory; reparse = false; return false; } public override bool DeleteFile(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { reparse = true; linkFound = true; error = ErrorCode.NoError; if (! (p.Length == 0) ) link = symbolicLink + SbUtils.PathString(p); else link = symbolicLink ; return false; } public override bool DeleteLink(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { reparse = true; linkFound = true; error = ErrorCode.NoError; if (! (p.Length == 0) ) link = symbolicLink + SbUtils.PathString(p); else link = symbolicLink ; return false; } public override bool GetLinkValue(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { reparse = true; linkFound = true; error = ErrorCode.NoError; // this is a traverse operation if (! (p.Length == 0) ) { link = symbolicLink + SbUtils.PathString(p); return false; } link = symbolicLink; return true; } public override bool QueryACL(StringBuilder! p, Principal pr, out bool linkFound, out ErrorCode error, out bool reparse, out string link, out Acl acl ) { reparse = true; linkFound = true; error = ErrorCode.NoError; reparse = true; acl = new Acl(); if (! (p.Length == 0)) link = symbolicLink + SbUtils.PathString(p); else link = symbolicLink; return false; } public override bool StoreACL(StringBuilder! p, Principal pr, Acl acl, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { reparse = true; linkFound = true; error = ErrorCode.NoError; if (! (p.Length == 0)) link = symbolicLink + SbUtils.PathString(p); else link = symbolicLink; return false; } } }