none
Automated permissions application using AD

    Question

  • Hi,

    I've recently started on a process of updating details of employees on a database, the company has requested that the users signature is captured, saved to a jpeg and then they can digitally 'sign' documents to save on print and scan time and paper wasting...

    so, the jpegs are now ready in a folder, handily called <username>.jpg, does anyone know of a way to automatically propagate permissions using AD and VB or similar to make it so that only domain admins and the user can acccess these files?

    thanks in advance :)

    Tuesday, June 26, 2012 1:04 PM

Answers

  • I don't understand what you are attempting, but I will make a guess. First, the attributes shown in your screen shot are added to the Active Directory schema when you install Exchange. As far as I know, they can be used by you for any purpose. I will assume the following:

    • You have the attribute extensionAttribute1 (or any unused attribute) available for user objects in AD.
    • You want to consider all files in a specified folder. For each file you want to take the file name (without the extension) and find a user with a corresponding value assigned to the sAMAccountName attribute (the pre-Windows 2000 logon name).
    • All files in the folder are in the form username.jpg, where there is one period in the name, and the file names without the extension are unique in the folder.
    • If you find such a user, you want to assign the filename (with extension) to the extensionAttribute1 attribute of the user, and you want to grant the user RW permissions to the file.
    • If no user is found, you want to log the filename.

    The following has not been tested, but should get you started:

    Option Explicit

    Dim strLog, objLog, objRootDSE, strDNSDomain, objTrans
    Dim strFolder, objFSO, objFolder, objFile, strFile, strUser
    Dim strUserDN, objUser, strNetBIOSDomain, objShell, strCmd, intError

    ' Constants for log file.
    Const ForAppending = 8
    Const OpenAsASCII = 0
    Const CreateIfNotExist = True
    ' Constants for the NameTranslate object.
    Const ADS_NAME_INITTYPE_GC = 3
    Const ADS_NAME_TYPE_NT4 = 3
    Const ADS_NAME_TYPE_1779 = 1

    ' Specify the folder.
    strFolder = "c:\MyFolder"

    ' Specify log file.
    strLog = "c:\Scripts\Report.log"

    ' Open the log file for appending.
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objLog = objFSO.OpenTextFile(strlog, _
        ForAppending, CreateIfNotExist, OpenAsASCII)
    ' Write to the log file.
    objLog.WriteLine "My log file"
    objLog.WriteLine "Started: " & CStr(Now())

    ' Determine DNS name of domain from RootDSE.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")

    ' Use the NameTranslate object to find the NetBIOS domain name from the
    ' DNS domain name.
    Set objTrans = CreateObject("NameTranslate")
    objTrans.Init ADS_NAME_INITTYPE_GC, ""
    objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain
    strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
    ' Remove trailing backslash.
    strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)

    Set objShell = CreateObject("Wscript.Shell")

    ' Retrieve a reference to folder.
    Set objFolder = objFSO.GetFolder(strFolder)

    ' Enumerate files in the folder.
    For Each objFile In objFolder.Files
        strFile = objFile.Name
        strUser = Left(strFile, InStr(strFile, ".") -1)

        ' Use the Set method to specify the NT format of the user name.
        ' Trap error if user does not exist.
        On Error Resume Next
        objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strUser
        If (Err.Number <>  0) Then
            On Error GoTo 0
            ' The user with the specified sAMAccountName does not exist.
            objLog.WriteLine "User " & strUser & " not found, file " & strFile & " skipped"
        Else
            On Error GoTo 0
            ' Use the Get method to retrieve the RPC 1779 Distinguished Name.
            strUserDN = objTrans.Get(ADS_NAME_TYPE_1779)
            ' Bind to the user object.
            Set objUser = GetObject("LDAP://" & strUserDN)
            ' Assign extensionAttribute1.
            objUser.extensionAttribute1 = strFile
            objUser.SetInfo
            ' Grant the user RW permissions to the file.
            strCmd = "%comspec% /c echo Y| cacls " & objFile.Path _
                & " /E /C /G " _
                & strNetBIOSDomain & "\" & strUser & ":RW"
            intError = objShell.Run(strCmd, 2, True)
            If (intError <> 0) Then
                objLog.WriteLine "Error assigning permissions for user " & strUser & " to file " & strFile
            End If
        End If
    Next

    ' Clean up.
    objLog.WriteLine "Finished: " & CStr(Now())
    objLog.Close
    Wscript.Echo "Done"

    -----



    Richard Mueller - MVP Directory Services

    Monday, July 09, 2012 5:04 PM

All replies

  • Hi,

    I've recently started on a process of updating details of employees on a database, the company has requested that the users signature is captured, saved to a jpeg and then they can digitally 'sign' documents to save on print and scan time and paper wasting...

    so, the jpegs are now ready in a folder, handily called <username>.jpg, does anyone know of a way to automatically propagate permissions using AD and VB or similar to make it so that only domain admins and the user can acccess these files?

    thanks in advance :)

    Place the signatures into the users 'My Documetns' folder as it is secured.

    Once the signature is used to sign a document anyome can copy it.  Tis is not very secure.  Why not use a certificat.  Certs can be stored in AD very easily.


    ¯\_(ツ)_/¯

    Tuesday, June 26, 2012 1:50 PM
  • certificates are better; but not useful for the media printed later, which is the requirement here.

    There are also occasions when this sort of programming would be useful to me, retroactively adding an extension attribute or similar, any advice? :)

    Tuesday, June 26, 2012 5:59 PM
  • I don't know what yu mena by extensions.  The saem answer is still liely to be the best answer:

    Place the signatures into the users 'My Documents' folder as it is secured to the user and accessible by admins.


    ¯\_(ツ)_/¯

    Tuesday, June 26, 2012 8:01 PM
  • In Active Directory, as well as Name, username, email address, etc, you have the option (in advanced mode) to add extension atttributes:

    a screenshot can be seen at http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-25-31-metablogapi/6215.image_5F00_15F34E45.png (not one of mine, but you get the idea).

    So I shall rephrase my question into a more general form:

    Is there a way to poll AD for username and apply actions to a file based on informationin the filename, eg (in psuedo-code)

         ForEach file in (directory) get Filename.jpg

         if FromActiveDirectory is Filename = (any username)

              Permissions."Filename.jpg" = rw for username

              Change Attribute_X to filename.jpg

         Else

              log Filename.jpg as unexpected file to investigate

         EndIf

         Next

    This would save me quite a bit of data entry time eevery time we enhance our infrastructure :)

    Wednesday, June 27, 2012 5:57 AM
  • In Active Directory, as well as Name, username, email address, etc, you have the option (in advanced mode) to add extension atttributes:

    a screenshot can be seen at http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-25-31-metablogapi/6215.image_5F00_15F34E45.png (not one of mine, but you get the idea).

    So I shall rephrase my question into a more general form:

    Is there a way to poll AD for username and apply actions to a file based on informationin the filename, eg (in psuedo-code)

         ForEach file in (directory) get Filename.jpg

         if FromActiveDirectory is Filename = (any username)

              Permissions."Filename.jpg" = rw for username

              Change Attribute_X to filename.jpg

         Else

              log Filename.jpg as unexpected file to investigate

         EndIf

         Next

    This would save me quite a bit of data entry time eevery time we enhance our infrastructure :)

    Your questin is still very vague.

    AD cannot automaticall change any permissions. 

    Are youasking if it is possible to store a filename into AD using one of the extended attributes?  If that is the question then yes - just set the atribute to the file name.

    When you create the files you will need to set the permissions.  This has nothing to do with Active Directory.  Active Directory does not manage files or permisisons.  FIles and permissions are managed by the file system and the user who owns the file.

    You can use CACLS, ICACLS or any number of ohter commandline utilities to set file permissons.


    ¯\_(ツ)_/¯

    Wednesday, June 27, 2012 2:35 PM
  • I don't understand what you are attempting, but I will make a guess. First, the attributes shown in your screen shot are added to the Active Directory schema when you install Exchange. As far as I know, they can be used by you for any purpose. I will assume the following:

    • You have the attribute extensionAttribute1 (or any unused attribute) available for user objects in AD.
    • You want to consider all files in a specified folder. For each file you want to take the file name (without the extension) and find a user with a corresponding value assigned to the sAMAccountName attribute (the pre-Windows 2000 logon name).
    • All files in the folder are in the form username.jpg, where there is one period in the name, and the file names without the extension are unique in the folder.
    • If you find such a user, you want to assign the filename (with extension) to the extensionAttribute1 attribute of the user, and you want to grant the user RW permissions to the file.
    • If no user is found, you want to log the filename.

    The following has not been tested, but should get you started:

    Option Explicit

    Dim strLog, objLog, objRootDSE, strDNSDomain, objTrans
    Dim strFolder, objFSO, objFolder, objFile, strFile, strUser
    Dim strUserDN, objUser, strNetBIOSDomain, objShell, strCmd, intError

    ' Constants for log file.
    Const ForAppending = 8
    Const OpenAsASCII = 0
    Const CreateIfNotExist = True
    ' Constants for the NameTranslate object.
    Const ADS_NAME_INITTYPE_GC = 3
    Const ADS_NAME_TYPE_NT4 = 3
    Const ADS_NAME_TYPE_1779 = 1

    ' Specify the folder.
    strFolder = "c:\MyFolder"

    ' Specify log file.
    strLog = "c:\Scripts\Report.log"

    ' Open the log file for appending.
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objLog = objFSO.OpenTextFile(strlog, _
        ForAppending, CreateIfNotExist, OpenAsASCII)
    ' Write to the log file.
    objLog.WriteLine "My log file"
    objLog.WriteLine "Started: " & CStr(Now())

    ' Determine DNS name of domain from RootDSE.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")

    ' Use the NameTranslate object to find the NetBIOS domain name from the
    ' DNS domain name.
    Set objTrans = CreateObject("NameTranslate")
    objTrans.Init ADS_NAME_INITTYPE_GC, ""
    objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain
    strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
    ' Remove trailing backslash.
    strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)

    Set objShell = CreateObject("Wscript.Shell")

    ' Retrieve a reference to folder.
    Set objFolder = objFSO.GetFolder(strFolder)

    ' Enumerate files in the folder.
    For Each objFile In objFolder.Files
        strFile = objFile.Name
        strUser = Left(strFile, InStr(strFile, ".") -1)

        ' Use the Set method to specify the NT format of the user name.
        ' Trap error if user does not exist.
        On Error Resume Next
        objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strUser
        If (Err.Number <>  0) Then
            On Error GoTo 0
            ' The user with the specified sAMAccountName does not exist.
            objLog.WriteLine "User " & strUser & " not found, file " & strFile & " skipped"
        Else
            On Error GoTo 0
            ' Use the Get method to retrieve the RPC 1779 Distinguished Name.
            strUserDN = objTrans.Get(ADS_NAME_TYPE_1779)
            ' Bind to the user object.
            Set objUser = GetObject("LDAP://" & strUserDN)
            ' Assign extensionAttribute1.
            objUser.extensionAttribute1 = strFile
            objUser.SetInfo
            ' Grant the user RW permissions to the file.
            strCmd = "%comspec% /c echo Y| cacls " & objFile.Path _
                & " /E /C /G " _
                & strNetBIOSDomain & "\" & strUser & ":RW"
            intError = objShell.Run(strCmd, 2, True)
            If (intError <> 0) Then
                objLog.WriteLine "Error assigning permissions for user " & strUser & " to file " & strFile
            End If
        End If
    Next

    ' Clean up.
    objLog.WriteLine "Finished: " & CStr(Now())
    objLog.Close
    Wscript.Echo "Done"

    -----



    Richard Mueller - MVP Directory Services

    Monday, July 09, 2012 5:04 PM