From d3e82e640cd493f640dfe8028e6d391e1ba576d9 Mon Sep 17 00:00:00 2001 From: Axton Grams Date: Tue, 4 May 2021 13:31:11 -0400 Subject: [PATCH 1/4] Added new provider configuration parameter winrm_pass_credentials to address issue #99 --- ad/config.go | 43 +++++++------- ad/data_source_ad_computer.go | 3 +- ad/data_source_ad_gpo.go | 3 +- ad/data_source_ad_group.go | 3 +- ad/data_source_ad_ou.go | 3 +- ad/data_source_ad_user.go | 4 +- ad/internal/winrmhelper/winrm_computer.go | 18 +++--- ad/internal/winrmhelper/winrm_gplink.go | 18 +++--- ad/internal/winrmhelper/winrm_gpo.go | 56 +++++++++---------- ad/internal/winrmhelper/winrm_group.go | 29 ++++++---- .../winrmhelper/winrm_group_membership.go | 36 ++++++------ ad/internal/winrmhelper/winrm_helper.go | 33 +++++++++-- ad/internal/winrmhelper/winrm_ou.go | 20 +++---- ad/internal/winrmhelper/winrm_sec.go | 18 +++--- ad/internal/winrmhelper/winrm_user.go | 20 +++---- ad/provider.go | 21 +++++++ ad/resource_ad_computer.go | 12 ++-- ad/resource_ad_gplink.go | 12 ++-- ad/resource_ad_gpo.go | 12 ++-- ad/resource_ad_gpo_security.go | 24 ++++---- ad/resource_ad_group.go | 15 +++-- ad/resource_ad_group_membership.go | 12 ++-- ad/resource_ad_ou.go | 12 ++-- ad/resource_ad_user.go | 14 +++-- docs/index.md | 15 +++++ go.mod | 2 + 26 files changed, 284 insertions(+), 174 deletions(-) diff --git a/ad/config.go b/ad/config.go index 92c05544..bba822ed 100644 --- a/ad/config.go +++ b/ad/config.go @@ -22,16 +22,17 @@ import ( // ProviderConfig holds all the information necessary to configure the provider type ProviderConfig struct { - WinRMUsername string - WinRMPassword string - WinRMHost string - WinRMPort int - WinRMProto string - WinRMInsecure bool - KrbRealm string - KrbConfig string - KrbSpn string - WinRMUseNTLM bool + WinRMUsername string + WinRMPassword string + WinRMHost string + WinRMPort int + WinRMProto string + WinRMInsecure bool + KrbRealm string + KrbConfig string + KrbSpn string + WinRMUseNTLM bool + WinRMPassCredentials bool } // NewConfig returns a new Config struct populated with Resource Data. @@ -47,18 +48,20 @@ func NewConfig(d *schema.ResourceData) ProviderConfig { krbConfig := d.Get("krb_conf").(string) krbSpn := d.Get("krb_spn").(string) winRMUseNTLM := d.Get("winrm_use_ntlm").(bool) + winRMPassCredentials := d.Get("winrm_pass_credentials").(bool) cfg := ProviderConfig{ - WinRMHost: winRMHost, - WinRMPort: winRMPort, - WinRMProto: winRMProto, - WinRMUsername: winRMUsername, - WinRMPassword: winRMPassword, - WinRMInsecure: winRMInsecure, - KrbRealm: krbRealm, - KrbConfig: krbConfig, - KrbSpn: krbSpn, - WinRMUseNTLM: winRMUseNTLM, + WinRMHost: winRMHost, + WinRMPort: winRMPort, + WinRMProto: winRMProto, + WinRMUsername: winRMUsername, + WinRMPassword: winRMPassword, + WinRMInsecure: winRMInsecure, + KrbRealm: krbRealm, + KrbConfig: krbConfig, + KrbSpn: krbSpn, + WinRMUseNTLM: winRMUseNTLM, + WinRMPassCredentials: winRMPassCredentials, } return cfg diff --git a/ad/data_source_ad_computer.go b/ad/data_source_ad_computer.go index a018a4c8..82261d65 100644 --- a/ad/data_source_ad_computer.go +++ b/ad/data_source_ad_computer.go @@ -38,6 +38,7 @@ func dataSourceADComputer() *schema.Resource { func dataSourceADComputerRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -56,7 +57,7 @@ func dataSourceADComputerRead(d *schema.ResourceData, meta interface{}) error { identity = dn } - computer, err := winrmhelper.NewComputerFromHost(client, identity, isLocal) + computer, err := winrmhelper.NewComputerFromHost(client, identity, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } diff --git a/ad/data_source_ad_gpo.go b/ad/data_source_ad_gpo.go index a14d990b..56303ea0 100644 --- a/ad/data_source_ad_gpo.go +++ b/ad/data_source_ad_gpo.go @@ -33,6 +33,7 @@ func dataSourceADGPO() *schema.Resource { func dataSourceADGPORead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() name := winrmhelper.SanitiseTFInput(d, "name") guid := winrmhelper.SanitiseTFInput(d, "guid") @@ -42,7 +43,7 @@ func dataSourceADGPORead(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - gpo, err := winrmhelper.GetGPOFromHost(client, name, guid, isLocal) + gpo, err := winrmhelper.GetGPOFromHost(client, name, guid, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "GpoWithNameNotFound") || strings.Contains(err.Error(), "GpoWithIdNotFound") { d.SetId("") diff --git a/ad/data_source_ad_group.go b/ad/data_source_ad_group.go index 68c07512..2e6ad6eb 100644 --- a/ad/data_source_ad_group.go +++ b/ad/data_source_ad_group.go @@ -64,6 +64,7 @@ func dataSourceADGroup() *schema.Resource { func dataSourceADGroupRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -72,7 +73,7 @@ func dataSourceADGroupRead(d *schema.ResourceData, meta interface{}) error { groupID := d.Get("group_id").(string) - g, err := winrmhelper.GetGroupFromHost(client, groupID, isLocal) + g, err := winrmhelper.GetGroupFromHost(client, groupID, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } diff --git a/ad/data_source_ad_ou.go b/ad/data_source_ad_ou.go index 7b563169..8a004063 100644 --- a/ad/data_source_ad_ou.go +++ b/ad/data_source_ad_ou.go @@ -44,6 +44,7 @@ func dataSourceADOU() *schema.Resource { func dataSourceADOURead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -58,7 +59,7 @@ func dataSourceADOURead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("invalid inputs, dn or a combination of path and name are required") } - ou, err := winrmhelper.NewOrgUnitFromHost(client, dn, name, path, isLocal) + ou, err := winrmhelper.NewOrgUnitFromHost(client, dn, name, path, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } diff --git a/ad/data_source_ad_user.go b/ad/data_source_ad_user.go index 8d82a744..203ebe1e 100644 --- a/ad/data_source_ad_user.go +++ b/ad/data_source_ad_user.go @@ -189,6 +189,8 @@ func dataSourceADUser() *schema.Resource { func dataSourceADUserRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() + userID := d.Get("user_id").(string) client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { @@ -196,7 +198,7 @@ func dataSourceADUserRead(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - u, err := winrmhelper.GetUserFromHost(client, userID, nil, isLocal) + u, err := winrmhelper.GetUserFromHost(client, userID, nil, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } diff --git a/ad/internal/winrmhelper/winrm_computer.go b/ad/internal/winrmhelper/winrm_computer.go index 84ec7d87..daecea8f 100644 --- a/ad/internal/winrmhelper/winrm_computer.go +++ b/ad/internal/winrmhelper/winrm_computer.go @@ -35,9 +35,9 @@ func NewComputerFromResource(d *schema.ResourceData) *Computer { // NewComputerFromHost return a new Machine struct populated from data we get // from the domain controller -func NewComputerFromHost(conn *winrm.Client, identity string, execLocally bool) (*Computer, error) { +func NewComputerFromHost(conn *winrm.Client, identity string, execLocally bool, passCredentials bool, username string, password string) (*Computer, error) { cmd := fmt.Sprintf("Get-ADComputer -Identity %q -Properties *", identity) - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return nil, fmt.Errorf("winrm execution failure in NewComputerFromHost: %s", err) } @@ -55,7 +55,7 @@ func NewComputerFromHost(conn *winrm.Client, identity string, execLocally bool) } // Create creates a new Computer object in the AD tree -func (m *Computer) Create(conn *winrm.Client, execLocally bool) (string, error) { +func (m *Computer) Create(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { if m.Name == "" { return "", fmt.Errorf("Computer.Create: missing name variable") } @@ -73,7 +73,7 @@ func (m *Computer) Create(conn *winrm.Client, execLocally bool) (string, error) cmd = fmt.Sprintf("%s -Description %q", cmd, m.Description) } - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return "", fmt.Errorf("winrm execution failure while creating computer object: %s", err) } @@ -90,14 +90,14 @@ func (m *Computer) Create(conn *winrm.Client, execLocally bool) (string, error) } // Update updates an existing Computer objects in the AD tree -func (m *Computer) Update(conn *winrm.Client, changes map[string]interface{}, execLocally bool) error { +func (m *Computer) Update(conn *winrm.Client, changes map[string]interface{}, execLocally bool, passCredentials bool, username string, password string) error { if m.GUID == "" { return fmt.Errorf("cannot update computer object with name %q, guid is not set", m.Name) } if path, ok := changes["container"]; ok { cmd := fmt.Sprintf("Move-AdObject -Identity %q -TargetPath %q", m.GUID, path.(string)) - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("winrm execution failure while moving computer object: %s", err) } @@ -113,7 +113,7 @@ func (m *Computer) Update(conn *winrm.Client, changes map[string]interface{}, ex description = fmt.Sprintf("%q", description) } cmd := fmt.Sprintf("Set-ADComputer -Identity %q -Description %s", m.GUID, description) - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("winrm execution failure while modifying computer description: %s", err) } @@ -126,9 +126,9 @@ func (m *Computer) Update(conn *winrm.Client, changes map[string]interface{}, ex } // Delete deletes an existing Computer objects from the AD tree -func (m *Computer) Delete(conn *winrm.Client, execLocally bool) error { +func (m *Computer) Delete(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf("Remove-ADComputer -confirm:$false -Identity %q", m.GUID) - result, err := RunWinRMCommand(conn, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("winrm execution failure while removing computer object: %s", err) } diff --git a/ad/internal/winrmhelper/winrm_gplink.go b/ad/internal/winrmhelper/winrm_gplink.go index a3ccbb68..bc8a7907 100644 --- a/ad/internal/winrmhelper/winrm_gplink.go +++ b/ad/internal/winrmhelper/winrm_gplink.go @@ -23,7 +23,7 @@ type GPLink struct { } //NewGPLink creates a link between a GPO and an AD object -func (g *GPLink) NewGPLink(client *winrm.Client, execLocally bool) (string, error) { +func (g *GPLink) NewGPLink(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { log.Printf("[DEBUG] Creating new user") enforced := "No" if g.Enforced { @@ -41,7 +41,7 @@ func (g *GPLink) NewGPLink(client *winrm.Client, execLocally bool) (string, erro cmds = append(cmds, fmt.Sprintf("-Order %d", g.Order)) } - result, err := RunWinRMCommand(client, cmds, true, false, execLocally) + result, err := RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) if err != nil { return "", err } @@ -59,7 +59,7 @@ func (g *GPLink) NewGPLink(client *winrm.Client, execLocally bool) (string, erro return "", fmt.Errorf("error while unmarshalling gplink json document: %s", err) } - ou, err := NewOrgUnitFromHost(client, gplink.Target, "", "", execLocally) + ou, err := NewOrgUnitFromHost(client, gplink.Target, "", "", execLocally, passCredentials, username, password) if err != nil { return "", fmt.Errorf("failed to retrieve details for OU %q: %s", gplink.Target, err) } @@ -71,7 +71,7 @@ func (g *GPLink) NewGPLink(client *winrm.Client, execLocally bool) (string, erro } //ModifyGPLink changes a GPO link -func (g *GPLink) ModifyGPLink(client *winrm.Client, changes map[string]interface{}, execLocally bool) error { +func (g *GPLink) ModifyGPLink(client *winrm.Client, changes map[string]interface{}, execLocally bool, passCredentials bool, username string, password string) error { cmds := []string{fmt.Sprintf("Set-GPLink -guid %q -target %q", g.GPOGuid, g.Target)} keyMap := map[string]string{ "enforced": "Enforced", @@ -95,7 +95,7 @@ func (g *GPLink) ModifyGPLink(client *winrm.Client, changes map[string]interface if len(cmds) == 1 { return nil } - result, err := RunWinRMCommand(client, cmds, false, false, execLocally) + result, err := RunWinRMCommand(client, cmds, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("error while running Set-GPLink: %s", err) } @@ -108,9 +108,9 @@ func (g *GPLink) ModifyGPLink(client *winrm.Client, changes map[string]interface } //RemoveGPLink deletes a link between a GPO and an AD object -func (g *GPLink) RemoveGPLink(client *winrm.Client, execLocally bool) error { +func (g *GPLink) RemoveGPLink(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf("Remove-GPlink -Guid %q -Target %q", g.GPOGuid, g.Target) - _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { // Check if the resource is already deleted if strings.Contains(err.Error(), "GpoLinkNotFound") || strings.Contains(err.Error(), "GpoWithIdNotFound") || strings.Contains(err.Error(), "There is no such object on the server") { @@ -136,9 +136,9 @@ func GetGPLinkFromResource(d *schema.ResourceData) *GPLink { //GetGPLinkFromHost returns a GPLink struct populated with data retrieved from the //Domain Controller -func GetGPLinkFromHost(client *winrm.Client, gpoGUID, containerGUID string, execLocally bool) (*GPLink, error) { +func GetGPLinkFromHost(client *winrm.Client, gpoGUID, containerGUID string, execLocally bool, passCredentials bool, username string, password string) (*GPLink, error) { cmds := []string{fmt.Sprintf("Get-ADObject -filter {ObjectGUID -eq %q} -properties gplink", containerGUID)} - result, err := RunWinRMCommand(client, cmds, true, false, execLocally) + result, err := RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) if err != nil { return nil, fmt.Errorf("while running Get-ADObject: %s", err) } diff --git a/ad/internal/winrmhelper/winrm_gpo.go b/ad/internal/winrmhelper/winrm_gpo.go index 5bf6199b..262ee830 100644 --- a/ad/internal/winrmhelper/winrm_gpo.go +++ b/ad/internal/winrmhelper/winrm_gpo.go @@ -66,7 +66,7 @@ func unmarshallGPO(input []byte) (*GPO, error) { } // GetGPOFromHost returns a GPO structure populated by data from the DC server -func GetGPOFromHost(conn *winrm.Client, name, guid string, execLocally bool) (*GPO, error) { +func GetGPOFromHost(conn *winrm.Client, name, guid string, execLocally bool, passCredentials bool, username string, password string) (*GPO, error) { start := time.Now().Unix() var cmd string if name != "" { @@ -74,7 +74,7 @@ func GetGPOFromHost(conn *winrm.Client, name, guid string, execLocally bool) (*G } else if guid != "" { cmd = getGPOCmdByGUID(guid) } - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return nil, err } @@ -86,13 +86,13 @@ func GetGPOFromHost(conn *winrm.Client, name, guid string, execLocally bool) (*G return nil, err } - basePath, err := gpo.loadGPOBasePath(conn, execLocally) + basePath, err := gpo.loadGPOBasePath(conn, execLocally, passCredentials, username, password) if err != nil { return nil, err } gpo.basePath = basePath - err = gpo.loadGPTIni(conn, execLocally) + err = gpo.loadGPTIni(conn, execLocally, passCredentials, username, password) if err != nil { return nil, err } @@ -120,7 +120,7 @@ func GetGPOFromResource(d *schema.ResourceData) *GPO { } // Rename renames a GPO to the given name -func (g *GPO) Rename(client *winrm.Client, target string, execLocally bool) error { +func (g *GPO) Rename(client *winrm.Client, target string, execLocally bool, passCredentials bool, username string, password string) error { if g.ID == "" { return fmt.Errorf("gpo guid required") } @@ -131,7 +131,7 @@ func (g *GPO) Rename(client *winrm.Client, target string, execLocally bool) erro cmds = append(cmds, fmt.Sprintf("-Domain %s", g.Domain)) } cmd := strings.Join(cmds, " ") - _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -139,9 +139,9 @@ func (g *GPO) Rename(client *winrm.Client, target string, execLocally bool) erro } //ChangeStatus Changes the status of a GPO -func (g *GPO) ChangeStatus(client *winrm.Client, status string, execLocally bool) error { +func (g *GPO) ChangeStatus(client *winrm.Client, status string, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf(`(%s).GpoStatus = "%s"`, getGPOCmdByGUID(g.ID), status) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -154,7 +154,7 @@ func (g *GPO) ChangeStatus(client *winrm.Client, status string, execLocally bool } // NewGPO uses Powershell over WinRM to create a script -func (g *GPO) NewGPO(client *winrm.Client, execLocally bool) (string, error) { +func (g *GPO) NewGPO(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { if g.Name == "" { return "", fmt.Errorf("gpo name required") @@ -170,7 +170,7 @@ func (g *GPO) NewGPO(client *winrm.Client, execLocally bool) (string, error) { cmds = append(cmds, fmt.Sprintf("-Comment %q", g.Description)) } - result, err := RunWinRMCommand(client, cmds, true, false, execLocally) + result, err := RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) if err != nil { return "", err } @@ -189,9 +189,9 @@ func (g *GPO) NewGPO(client *winrm.Client, execLocally bool) (string, error) { } // DeleteGPO delete the GPO container -func (g *GPO) DeleteGPO(client *winrm.Client, execLocally bool) error { +func (g *GPO) DeleteGPO(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf("Remove-GPO -Name %s -Domain %s", g.Name, g.Domain) - _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { // Check if the resource is already deleted if strings.Contains(err.Error(), "GpoWithNameNotFound") { @@ -203,16 +203,16 @@ func (g *GPO) DeleteGPO(client *winrm.Client, execLocally bool) error { } // UpdateGPO updates the GPO container -func (g *GPO) UpdateGPO(client *winrm.Client, d *schema.ResourceData, execLocally bool) (string, error) { +func (g *GPO) UpdateGPO(client *winrm.Client, d *schema.ResourceData, execLocally bool, passCredentials bool, username string, password string) (string, error) { if d.HasChange("name") { - err := g.Rename(client, SanitiseTFInput(d, "name"), execLocally) + err := g.Rename(client, SanitiseTFInput(d, "name"), execLocally, passCredentials, username, password) if err != nil { return "", err } } if d.HasChange("status") { - err := g.ChangeStatus(client, SanitiseTFInput(d, "status"), execLocally) + err := g.ChangeStatus(client, SanitiseTFInput(d, "status"), execLocally, passCredentials, username, password) if err != nil { return "", err } @@ -223,9 +223,9 @@ func (g *GPO) UpdateGPO(client *winrm.Client, d *schema.ResourceData, execLocall // getGPOFilePath retrieves the AD Object of a GPO via powershell and returns the gPCFileSysPath // property. This property points at the UNC that the GPO stores its configuration. We use the output // of this function as well as GetsysVolPath to construct the GPO path on the DC's filesystem. -func (g *GPO) getGPOFilePath(client *winrm.Client, execLocally bool) (string, error) { +func (g *GPO) getGPOFilePath(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { cmd := fmt.Sprintf("(Get-ADObject -LDAPFilter '(&(objectClass=groupPolicyContainer)(cn={%s}))' -Properties gPCFilesysPath).gPCFilesysPath", g.ID) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return "", fmt.Errorf("error while retrieving GPO with %q path: %s", g.ID, err) } @@ -237,9 +237,9 @@ func (g *GPO) getGPOFilePath(client *winrm.Client, execLocally bool) (string, er //getSysVolPath returns the local path for the SYSVOL share on a Domain Controller. The combination of this // and the value we get from getGPOFilePath is used to construct the GPO path on the DC's filesystem. -func getSysVolPath(client *winrm.Client, execLocally bool) (string, error) { +func getSysVolPath(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { cmd := "(Get-SmbShare sysvol).path" - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return "", fmt.Errorf("error while retrieving SYSVOL path") } @@ -251,15 +251,15 @@ func getSysVolPath(client *winrm.Client, execLocally bool) (string, error) { // GetGPOBasePath returns the base path of a GPO on the DC. All GPO related files go // in that location. -func (g *GPO) loadGPOBasePath(client *winrm.Client, execLocally bool) (string, error) { - gpoPath, err := g.getGPOFilePath(client, execLocally) +func (g *GPO) loadGPOBasePath(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { + gpoPath, err := g.getGPOFilePath(client, execLocally, passCredentials, username, password) if err != nil { return "", err } // gpoPath is a UNC. The first bit is the hostname and the second the share name // We are interested for the rest gPath := strings.Join(strings.Split(gpoPath, "\\")[4:], "\\") - sysvolPath, err := getSysVolPath(client, execLocally) + sysvolPath, err := getSysVolPath(client, execLocally, passCredentials, username, password) if err != nil { return "", err } @@ -285,9 +285,9 @@ func (g *GPO) loadGPOVersions(client *winrm.Client, gpoPath string) error { } // SetADGPOVersions updates AD with the given versions for a GPO -func (g *GPO) SetADGPOVersions(client *winrm.Client, gpoVersion uint32, execLocally bool) error { +func (g *GPO) SetADGPOVersions(client *winrm.Client, gpoVersion uint32, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf("$o=(Get-ADObject -LDAPFilter '(&(objectClass=groupPolicyContainer)(cn={%s}))' -Properties *);$o.VersionNumber=%d;Set-AdObject -Instance $o", g.ID, gpoVersion) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("error while setting new version in AD for GPO %q: %s", g.ID, err) } @@ -321,7 +321,7 @@ func (g *GPO) SetINIGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, g } // SetGPOVersions updates gpt.ini on the DC with the given values for user and computer version of a GPO. -func (g *GPO) SetGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, userVersion, computerVersion uint16, execLocally bool) error { +func (g *GPO) SetGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, userVersion, computerVersion uint16, execLocally bool, passCredentials bool, username string, password string) error { outBuf := make([]byte, 4) binary.LittleEndian.PutUint16(outBuf[:2], computerVersion) binary.LittleEndian.PutUint16(outBuf[2:], userVersion) @@ -332,18 +332,18 @@ func (g *GPO) SetGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, user return err } - err = g.SetADGPOVersions(client, newVersion, execLocally) + err = g.SetADGPOVersions(client, newVersion, execLocally, passCredentials, username, password) if err != nil { return err } return nil } -func (g *GPO) loadGPTIni(client *winrm.Client, execLocally bool) error { +func (g *GPO) loadGPTIni(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { gptPath := fmt.Sprintf("%s\\gpt.ini", g.basePath) log.Printf("[DEBUG] Getting GPT ini from %s", gptPath) cmd := fmt.Sprintf(`Get-Content "%s"`, gptPath) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("error while retrieving contents of %q: %s", gptPath, err) } diff --git a/ad/internal/winrmhelper/winrm_group.go b/ad/internal/winrmhelper/winrm_group.go index 56c167ba..c389b9be 100644 --- a/ad/internal/winrmhelper/winrm_group.go +++ b/ad/internal/winrmhelper/winrm_group.go @@ -26,7 +26,7 @@ type Group struct { } // AddGroup creates a new group -func (g *Group) AddGroup(client *winrm.Client, execLocally bool) (string, error) { +func (g *Group) AddGroup(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { log.Printf("[DEBUG] Adding group with name %q", g.Name) cmds := []string{fmt.Sprintf("New-ADGroup -Passthru -Name %q -GroupScope %q -GroupCategory %q -Path %q", g.Name, g.Scope, g.Category, g.Container)} @@ -38,7 +38,11 @@ func (g *Group) AddGroup(client *winrm.Client, execLocally bool) (string, error) cmds = append(cmds, fmt.Sprintf("-Description %q", g.Description)) } - result, err := RunWinRMCommand(client, cmds, true, false, execLocally) + var result *WinRMResult + var err error + + result, err = RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) + if err != nil { return "", err } @@ -60,7 +64,7 @@ func (g *Group) AddGroup(client *winrm.Client, execLocally bool) (string, error) } // ModifyGroup updates an existing group -func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLocally bool) error { +func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { KeyMap := map[string]string{ "sam_account_name": "SamAccountName", "scope": "GroupScope", @@ -83,7 +87,7 @@ func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLo } if len(cmds) > 1 { - result, err := RunWinRMCommand(client, cmds, false, false, execLocally) + result, err := RunWinRMCommand(client, cmds, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -95,7 +99,7 @@ func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLo if d.HasChange("name") { cmds := []string{"Rename-ADObject -Identity %q -NewName %q", g.GUID, d.Get("name").(string)} - result, err := RunWinRMCommand(client, cmds, false, false, execLocally) + result, err := RunWinRMCommand(client, cmds, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -107,7 +111,7 @@ func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLo if d.HasChange("container") { cmds := []string{"Rename-ADObject -Identity %q -NewName %q", g.GUID, d.Get("name").(string)} - result, err := RunWinRMCommand(client, cmds, false, false, execLocally) + result, err := RunWinRMCommand(client, cmds, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -122,9 +126,9 @@ func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLo } // DeleteGroup removes a group -func (g *Group) DeleteGroup(client *winrm.Client, execLocally bool) error { +func (g *Group) DeleteGroup(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf("Remove-ADGroup -Identity %s -Confirm:$false", g.GUID) - _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { // Check if the resource is already deleted if strings.Contains(err.Error(), "ADIdentityNotFoundException") { @@ -152,9 +156,14 @@ func GetGroupFromResource(d *schema.ResourceData) *Group { // GetGroupFromHost returns a Group struct based on data // retrieved from the AD Controller. -func GetGroupFromHost(client *winrm.Client, guid string, execLocally bool) (*Group, error) { +func GetGroupFromHost(client *winrm.Client, guid string, execLocally bool, passCredentials bool, username string, password string) (*Group, error) { cmd := fmt.Sprintf("Get-ADGroup -identity %q -properties *", guid) - result, err := RunWinRMCommand(client, []string{cmd}, true, false, execLocally) + + var result *WinRMResult + var err error + + result, err = RunWinRMCommand(client, []string{cmd}, true, false, execLocally, passCredentials, username, password) + if err != nil { return nil, err } diff --git a/ad/internal/winrmhelper/winrm_group_membership.go b/ad/internal/winrmhelper/winrm_group_membership.go index 151dafb3..29f21e8a 100644 --- a/ad/internal/winrmhelper/winrm_group_membership.go +++ b/ad/internal/winrmhelper/winrm_group_membership.go @@ -66,10 +66,10 @@ func getMembershipList(g []*GroupMember) string { return strings.Join(out, ",") } -func (g *GroupMembership) getGroupMembers(client *winrm.Client, execLocally bool) ([]*GroupMember, error) { +func (g *GroupMembership) getGroupMembers(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) ([]*GroupMember, error) { cmd := fmt.Sprintf("Get-ADGroupMember -Identity %q", g.GroupGUID) - result, err := RunWinRMCommand(client, []string{cmd}, true, true, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, true, true, execLocally, passCredentials, username, password) if err != nil { return nil, fmt.Errorf("while running Get-ADGroupMember: %s", err) } else if result.ExitCode != 0 { @@ -88,7 +88,7 @@ func (g *GroupMembership) getGroupMembers(client *winrm.Client, execLocally bool return gm, nil } -func (g *GroupMembership) bulkGroupMembersOp(client *winrm.Client, operation string, members []*GroupMember, execLocally bool) error { +func (g *GroupMembership) bulkGroupMembersOp(client *winrm.Client, operation string, members []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { if len(members) == 0 { return nil } @@ -96,7 +96,7 @@ func (g *GroupMembership) bulkGroupMembersOp(client *winrm.Client, operation str memberList := getMembershipList(members) cmd := fmt.Sprintf("%s -Identity %q %s -Confirm:$false", operation, g.GroupGUID, memberList) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("while running %s: %s", operation, err) } else if result.ExitCode != 0 { @@ -106,27 +106,27 @@ func (g *GroupMembership) bulkGroupMembersOp(client *winrm.Client, operation str return nil } -func (g *GroupMembership) addGroupMembers(client *winrm.Client, members []*GroupMember, execLocally bool) error { - return g.bulkGroupMembersOp(client, "Add-ADGroupMember", members, execLocally) +func (g *GroupMembership) addGroupMembers(client *winrm.Client, members []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { + return g.bulkGroupMembersOp(client, "Add-ADGroupMember", members, execLocally, passCredentials, username, password) } -func (g *GroupMembership) removeGroupMembers(client *winrm.Client, members []*GroupMember, execLocally bool) error { - return g.bulkGroupMembersOp(client, "Remove-ADGroupMember", members, execLocally) +func (g *GroupMembership) removeGroupMembers(client *winrm.Client, members []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { + return g.bulkGroupMembersOp(client, "Remove-ADGroupMember", members, execLocally, passCredentials, username, password) } -func (g *GroupMembership) Update(client *winrm.Client, expected []*GroupMember, execLocally bool) error { - existing, err := g.getGroupMembers(client, execLocally) +func (g *GroupMembership) Update(client *winrm.Client, expected []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { + existing, err := g.getGroupMembers(client, execLocally, passCredentials, username, password) if err != nil { return err } toAdd, toRemove := diffGroupMemberLists(expected, existing) - err = g.addGroupMembers(client, toAdd, execLocally) + err = g.addGroupMembers(client, toAdd, execLocally, passCredentials, username, password) if err != nil { return err } - err = g.removeGroupMembers(client, toRemove, execLocally) + err = g.removeGroupMembers(client, toRemove, execLocally, passCredentials, username, password) if err != nil { return err } @@ -134,14 +134,14 @@ func (g *GroupMembership) Update(client *winrm.Client, expected []*GroupMember, return nil } -func (g *GroupMembership) Create(client *winrm.Client, execLocally bool) error { +func (g *GroupMembership) Create(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { if len(g.GroupMembers) == 0 { return nil } memberList := getMembershipList(g.GroupMembers) cmd := []string{fmt.Sprintf("Add-ADGroupMember -Identity %q -Members %s", g.GroupGUID, memberList)} - result, err := RunWinRMCommand(client, cmd, false, false, execLocally) + result, err := RunWinRMCommand(client, cmd, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("while running Add-ADGroupMember: %s", err) } else if result.ExitCode != 0 { @@ -151,9 +151,9 @@ func (g *GroupMembership) Create(client *winrm.Client, execLocally bool) error { return nil } -func (g *GroupMembership) Delete(client *winrm.Client, execLocally bool) error { +func (g *GroupMembership) Delete(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf("Remove-ADGroupMember %q -Members (Get-ADGroupMember %q) -Confirm:$false", g.GroupGUID, g.GroupGUID) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("while running Remove-ADGroupMember: %s", err) } else if result.ExitCode != 0 && !strings.Contains(result.StdErr, "InvalidData") { @@ -162,12 +162,12 @@ func (g *GroupMembership) Delete(client *winrm.Client, execLocally bool) error { return nil } -func NewGroupMembershipFromHost(client *winrm.Client, groupID string, execLocally bool) (*GroupMembership, error) { +func NewGroupMembershipFromHost(client *winrm.Client, groupID string, execLocally bool, passCredentials bool, username string, password string) (*GroupMembership, error) { result := &GroupMembership{ GroupGUID: groupID, } - gm, err := result.getGroupMembers(client, execLocally) + gm, err := result.getGroupMembers(client, execLocally, passCredentials, username, password) if err != nil { return nil, err } diff --git a/ad/internal/winrmhelper/winrm_helper.go b/ad/internal/winrmhelper/winrm_helper.go index a1b3b2f4..69f65938 100644 --- a/ad/internal/winrmhelper/winrm_helper.go +++ b/ad/internal/winrmhelper/winrm_helper.go @@ -124,17 +124,38 @@ func (p *PowerShell) ExecutePScmd(args ...string) (stdout string, stderr string, return } -// RunWinRMCommand will run a powershell command and return the stdout and stderr +// RunWinRMCommandWithCreds will run a powershell command and return the stdout and stderr // The output is converted to JSON if the json patameter is set to true. -func RunWinRMCommand(conn *winrm.Client, cmds []string, json bool, forceArray bool, execLocally bool) (*WinRMResult, error) { +func RunWinRMCommand(conn *winrm.Client, cmds []string, json bool, forceArray bool, execLocally bool, passCredentials bool, username string, password string) (*WinRMResult, error) { + if passCredentials { + cmds = append(cmds, "-Credential $Credential") + } + if json { cmds = append(cmds, "| ConvertTo-Json") } + cmd_redacted := strings.Join(cmds, " ") + encodedCmdRedacted := winrm.Powershell(cmd_redacted) + + if passCredentials { + cmd_username := fmt.Sprintf("$User = \"%s\"\n", username) + cmd_password := fmt.Sprintf("$Password = ConvertTo-SecureString -String \"%s\" -AsPlainText -Force\n", password) + cmds = append([]string{"$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Password\n"}, cmds...) + cmds = append([]string{cmd_username}, cmds...) + cmds = append([]string{cmd_password}, cmds...) + } + cmd := strings.Join(cmds, " ") encodedCmd := winrm.Powershell(cmd) - log.Printf("[DEBUG] Running command %s via powershell", cmd) - log.Printf("[DEBUG] Encoded command: %s", encodedCmd) + + if passCredentials { + log.Printf("[DEBUG] Running command %s via powershell", cmd_redacted) + log.Printf("[DEBUG] Encoded command: %s", encodedCmdRedacted) + } else { + log.Printf("[DEBUG] Running command %s via powershell", cmd) + log.Printf("[DEBUG] Encoded command: %s", encodedCmd) + } var ( stdout string @@ -213,9 +234,9 @@ func SanitiseString(key string) string { // SetMachineExtensionName will add the necessary GUIDs to the GPO's gPCMachineExtensionNames attribute. // These are required for the security settings part of a GPO to work. -func SetMachineExtensionNames(client *winrm.Client, gpoDN, value string, execLocally bool) error { +func SetMachineExtensionNames(client *winrm.Client, gpoDN, value string, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf(`Set-ADObject -Identity "%s" -Replace @{gPCMachineExtensionNames="%s"}`, gpoDN, value) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("error while setting machine extension names for GPO %q: %s", gpoDN, err) } diff --git a/ad/internal/winrmhelper/winrm_ou.go b/ad/internal/winrmhelper/winrm_ou.go index 7d352c99..25766258 100644 --- a/ad/internal/winrmhelper/winrm_ou.go +++ b/ad/internal/winrmhelper/winrm_ou.go @@ -36,7 +36,7 @@ func NewOrgUnitFromResource(d *schema.ResourceData) *OrgUnit { // NewOrgUnitFromHost returns a new OrgUnit struct populated from data we get from // the domain controller -func NewOrgUnitFromHost(conn *winrm.Client, guid, name, path string, execLocally bool) (*OrgUnit, error) { +func NewOrgUnitFromHost(conn *winrm.Client, guid, name, path string, execLocally bool, passCredentials bool, username string, password string) (*OrgUnit, error) { var cmd string if guid != "" { cmd = fmt.Sprintf("Get-ADObject -Properties * -Identity %q", guid) @@ -46,7 +46,7 @@ func NewOrgUnitFromHost(conn *winrm.Client, guid, name, path string, execLocally return nil, fmt.Errorf("invalid inputs, dn or a combination of path and name are required") } - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return nil, err } @@ -63,7 +63,7 @@ func NewOrgUnitFromHost(conn *winrm.Client, guid, name, path string, execLocally } // Create creates a new OU in the AD tree -func (o *OrgUnit) Create(conn *winrm.Client, execLocally bool) (string, error) { +func (o *OrgUnit) Create(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { cmd := "New-ADOrganizationalUnit -Passthru" if o.Name == "" { @@ -81,7 +81,7 @@ func (o *OrgUnit) Create(conn *winrm.Client, execLocally bool) (string, error) { cmd = fmt.Sprintf("%s -ProtectedFromAccidentalDeletion:$%t", cmd, o.Protected) - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return "", err } @@ -97,7 +97,7 @@ func (o *OrgUnit) Create(conn *winrm.Client, execLocally bool) (string, error) { } // Update updates an existing OU in the AD tree -func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, execLocally bool) error { +func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, execLocally bool, passCredentials bool, username string, password string) error { if o.DistinguishedName == "" { return fmt.Errorf("Cannot update OU with name %q, distiguished name is empty", o.Name) } @@ -116,7 +116,7 @@ func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, exe } if cmd != "Set-ADOrganizationalUnit -Identity" { - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -127,7 +127,7 @@ func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, exe if protected, ok := changes["protected"]; ok { cmd = fmt.Sprintf("Set-ADObject -Identity %s -ProtectedFromAccidentalDeletion:$%t", o.GUID, protected.(bool)) - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -138,7 +138,7 @@ func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, exe if name, ok := changes["name"]; ok { cmd = fmt.Sprintf("Rename-ADObject -Identity %q %q ", o.GUID, name.(string)) - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -151,12 +151,12 @@ func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, exe } // Delete deletes an existing OU from an AD tree -func (o *OrgUnit) Delete(conn *winrm.Client, execLocally bool) error { +func (o *OrgUnit) Delete(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { if o.DistinguishedName == "" { return fmt.Errorf("Cannot remove OU with name %q, distiguished name is empty", o.Name) } cmd := fmt.Sprintf("Get-ADObject -Properties * -Identity %q | Set-ADObject -ProtectedFromAccidentalDeletion:$false -Passthru | Remove-ADOrganizationalUnit -confirm:$false", o.DistinguishedName) - result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return err } diff --git a/ad/internal/winrmhelper/winrm_sec.go b/ad/internal/winrmhelper/winrm_sec.go index 555af818..d4ea1b75 100644 --- a/ad/internal/winrmhelper/winrm_sec.go +++ b/ad/internal/winrmhelper/winrm_sec.go @@ -41,12 +41,12 @@ func GetSecIniFromResource(d *schema.ResourceData, schemaKeys map[string]*schema // GetSecIniContents returns a byte array with the contents of the INF file // encoded in UTF-8 (since we get the ouput via stdout). -func GetSecIniContents(client *winrm.Client, gpo *GPO, execLocally bool) ([]byte, error) { +func GetSecIniContents(client *winrm.Client, gpo *GPO, execLocally bool, passCredentials bool, username string, password string) ([]byte, error) { gptPath := fmt.Sprintf("%s\\Machine\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf", gpo.basePath) log.Printf("[DEBUG] Getting security settings inf from %s", gptPath) cmd := fmt.Sprintf(`Get-Content "%s"`, gptPath) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return nil, fmt.Errorf("error while retrieving contents of %q: %s", gptPath, err) } @@ -59,9 +59,9 @@ func GetSecIniContents(client *winrm.Client, gpo *GPO, execLocally bool) ([]byte } // GetSecIniFromHost returns a struct representing the data retrieved from the host. -func GetSecIniFromHost(client *winrm.Client, gpo *GPO, execLocally bool) (*gposec.SecuritySettings, error) { +func GetSecIniFromHost(client *winrm.Client, gpo *GPO, execLocally bool, passCredentials bool, username string, password string) (*gposec.SecuritySettings, error) { - iniBytes, err := GetSecIniContents(client, gpo, execLocally) + iniBytes, err := GetSecIniContents(client, gpo, execLocally, passCredentials, username, password) if err != nil { return nil, err } @@ -74,7 +74,7 @@ func GetSecIniFromHost(client *winrm.Client, gpo *GPO, execLocally bool) (*gpose // UploadSecIni uploads the security settings ini to the correct folder of a GPO and updates // the GPO's gpt.ini by incrementing the computer version by 1. -func UploadSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, iniFile *ini.File, execLocally bool) error { +func UploadSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, iniFile *ini.File, execLocally bool, passCredentials bool, username string, password string) error { ini.LineBreak = "\r\n" buf := bytes.NewBuffer([]byte{}) iniLocation := fmt.Sprintf("%s\\Machine\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf", gpo.basePath) @@ -88,7 +88,7 @@ func UploadSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, iniFile } cVer := gpo.computerVersion + 1 - err = gpo.SetGPOVersions(conn, cpConn, gpo.userVersion, cVer, execLocally) + err = gpo.SetGPOVersions(conn, cpConn, gpo.userVersion, cVer, execLocally, passCredentials, username, password) if err != nil { return err } @@ -97,12 +97,12 @@ func UploadSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, iniFile // RemoveSecIni removes the ini file from the host and updates the GPO's gpt.ini by incrementing the // computer version by 1. -func RemoveSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, execLocally bool) error { +func RemoveSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, execLocally bool, passCredentials bool, username string, password string) error { gptPath := fmt.Sprintf("%s\\Machine\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf", gpo.basePath) log.Printf("[DEBUG] Getting security settings inf from %s", gptPath) cmd := fmt.Sprintf(`Remove-Item "%s"`, gptPath) - result, err := RunWinRMCommand(conn, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(conn, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("error while retrieving contents of %q: %s", gptPath, err) } @@ -114,7 +114,7 @@ func RemoveSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, execLoc } cVer := gpo.computerVersion + 1 - err = gpo.SetGPOVersions(conn, cpConn, gpo.userVersion, cVer, execLocally) + err = gpo.SetGPOVersions(conn, cpConn, gpo.userVersion, cVer, execLocally, passCredentials, username, password) if err != nil { return err } diff --git a/ad/internal/winrmhelper/winrm_user.go b/ad/internal/winrmhelper/winrm_user.go index 8bd37cc7..ae1a12de 100644 --- a/ad/internal/winrmhelper/winrm_user.go +++ b/ad/internal/winrmhelper/winrm_user.go @@ -62,7 +62,7 @@ type User struct { } // NewUser creates the user by running the New-ADUser powershell command -func (u *User) NewUser(client *winrm.Client, execLocally bool) (string, error) { +func (u *User) NewUser(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { if u.Username == "" { return "", fmt.Errorf("user principal name required") } @@ -213,7 +213,7 @@ func (u *User) NewUser(client *winrm.Client, execLocally bool) (string, error) { cmds = append(cmds, fmt.Sprintf("-OtherAttributes %s", attrs)) } - result, err := RunWinRMCommand(client, cmds, true, false, execLocally) + result, err := RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) if err != nil { return "", err } @@ -234,7 +234,7 @@ func (u *User) NewUser(client *winrm.Client, execLocally bool) (string, error) { } // ModifyUser updates the AD user's details based on what's changed in the resource. -func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLocally bool) error { +func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { log.Printf("Modifying user: %q", u.PrincipalName) strKeyMap := map[string]string{ "sam_account_name": "SamAccountName", @@ -374,7 +374,7 @@ func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLoca } if len(cmds) > 1 { - result, err := RunWinRMCommand(client, cmds, false, false, execLocally) + result, err := RunWinRMCommand(client, cmds, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -386,7 +386,7 @@ func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLoca if d.HasChange("initial_password") { cmd := fmt.Sprintf("Set-ADAccountPassword -Identity %q -Reset -NewPassword (ConvertTo-SecureString -AsPlainText %q -Force)", u.GUID, u.Password) - result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -399,7 +399,7 @@ func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLoca if d.HasChange("container") { path := d.Get("container").(string) cmd := fmt.Sprintf("Move-AdObject -Identity %q -TargetPath %q", u.GUID, path) - result, err := RunWinRMCommand(client, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return fmt.Errorf("winrm execution failure while moving user object: %s", err) } @@ -412,9 +412,9 @@ func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLoca } //DeleteUser deletes an AD user by calling Remove-ADUser -func (u *User) DeleteUser(client *winrm.Client, execLocally bool) error { +func (u *User) DeleteUser(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { cmd := fmt.Sprintf("Remove-ADUser -Identity %s -Confirm:$false", u.GUID) - _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally) + _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { // Check if the resource is already deleted if strings.Contains(err.Error(), "ADIdentityNotFoundException") { @@ -512,9 +512,9 @@ func GetUserFromResource(d *schema.ResourceData) (*User, error) { // GetUserFromHost returns a User struct based on data // retrieved from the AD Domain Controller. -func GetUserFromHost(client *winrm.Client, guid string, customAttributes []string, execLocally bool) (*User, error) { +func GetUserFromHost(client *winrm.Client, guid string, customAttributes []string, execLocally bool, passCredentials bool, username string, password string) (*User, error) { cmd := fmt.Sprintf("Get-ADUser -identity %q -properties *", guid) - result, err := RunWinRMCommand(client, []string{cmd}, true, false, execLocally) + result, err := RunWinRMCommand(client, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return nil, err } diff --git a/ad/provider.go b/ad/provider.go index 9905c614..8e40c4b3 100644 --- a/ad/provider.go +++ b/ad/provider.go @@ -94,6 +94,12 @@ func Provider() *schema.Provider { DefaultFunc: schema.EnvDefaultFunc("AD_WINRM_USE_NTLM", false), Description: "Use NTLM authentication. (default: false, environment variable: AD_WINRM_USE_NTLM)", }, + "winrm_pass_credentials": { + Type: schema.TypeBool, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("AD_WINRM_PASS_CREDENTIALS", false), + Description: "Pass credentials in WinRM session to create a System.Management.Automation.PSCredential. (default: false, environment variable: AD_WINRM_PASS_CREDENTIALS)", + }, }, DataSourcesMap: map[string]*schema.Resource{ "ad_user": dataSourceADUser(), @@ -187,6 +193,21 @@ func (pcfg ProviderConf) isConnectionTypeLocal() bool { return isLocal } +// isPassCredentialsEnabled check if credentials should be passed +// requires that https be enabled +func (pcfg ProviderConf) isPassCredentialsEnabled() bool { + pcfg.mx.Lock() + defer pcfg.mx.Unlock() + log.Printf("[DEBUG] Checking to see if credentials should be passed") + isPassCredentialsEnabled := false + if pcfg.Configuration.WinRMProto == "https" && pcfg.Configuration.WinRMPassCredentials { + log.Printf("[DEBUG] Matching criteria for passing credenitals") + isPassCredentialsEnabled = true + } + log.Printf("[DEBUG] Pass Credentials ? %t", isPassCredentialsEnabled) + return isPassCredentialsEnabled +} + func initProviderConfig(d *schema.ResourceData) (interface{}, error) { cfg := NewConfig(d) diff --git a/ad/resource_ad_computer.go b/ad/resource_ad_computer.go index fae8c99d..0f3bbbe7 100644 --- a/ad/resource_ad_computer.go +++ b/ad/resource_ad_computer.go @@ -67,6 +67,7 @@ func resourceADComputerRead(d *schema.ResourceData, meta interface{}) error { } isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { @@ -74,7 +75,7 @@ func resourceADComputerRead(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - computer, err := winrmhelper.NewComputerFromHost(client, d.Id(), isLocal) + computer, err := winrmhelper.NewComputerFromHost(client, d.Id(), isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "ObjectNotFound") { // Resource no longer exists @@ -96,6 +97,7 @@ func resourceADComputerRead(d *schema.ResourceData, meta interface{}) error { func resourceADComputerCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -104,7 +106,7 @@ func resourceADComputerCreate(d *schema.ResourceData, meta interface{}) error { computer := winrmhelper.NewComputerFromResource(d) - guid, err := computer.Create(client, isLocal) + guid, err := computer.Create(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while creating new computer object: %s", err) } @@ -114,6 +116,7 @@ func resourceADComputerCreate(d *schema.ResourceData, meta interface{}) error { func resourceADComputerUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -129,7 +132,7 @@ func resourceADComputerUpdate(d *schema.ResourceData, meta interface{}) error { } } - err = computer.Update(client, changes, isLocal) + err = computer.Update(client, changes, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while updating computer with id %q: %s", d.Id(), err) } @@ -141,6 +144,7 @@ func resourceADComputerDelete(d *schema.ResourceData, meta interface{}) error { return nil } isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -148,7 +152,7 @@ func resourceADComputerDelete(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) computer := winrmhelper.NewComputerFromResource(d) - err = computer.Delete(client, isLocal) + err = computer.Delete(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while deleting a computer object with id %q: %s", d.Id(), err) } diff --git a/ad/resource_ad_gplink.go b/ad/resource_ad_gplink.go index b23d3966..a206b680 100644 --- a/ad/resource_ad_gplink.go +++ b/ad/resource_ad_gplink.go @@ -64,6 +64,7 @@ func resourceADGPLink() *schema.Resource { func resourceADGPLinkRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -74,7 +75,7 @@ func resourceADGPLinkRead(d *schema.ResourceData, meta interface{}) error { if len(idParts) != 2 { return fmt.Errorf("malformed ID for GPLink resource with ID %q", d.Id()) } - gplink, err := winrmhelper.GetGPLinkFromHost(client, idParts[0], idParts[1], isLocal) + gplink, err := winrmhelper.GetGPLinkFromHost(client, idParts[0], idParts[1], isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "did not find") { d.SetId("") @@ -94,6 +95,7 @@ func resourceADGPLinkRead(d *schema.ResourceData, meta interface{}) error { func resourceADGPLinkCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -101,7 +103,7 @@ func resourceADGPLinkCreate(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) gplink := winrmhelper.GetGPLinkFromResource(d) - gpLinkID, err := gplink.NewGPLink(client, isLocal) + gpLinkID, err := gplink.NewGPLink(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("while creating GPLink resource: %s", err) } @@ -112,6 +114,7 @@ func resourceADGPLinkCreate(d *schema.ResourceData, meta interface{}) error { func resourceADGPLinkUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -126,7 +129,7 @@ func resourceADGPLinkUpdate(d *schema.ResourceData, meta interface{}) error { } } gplink := winrmhelper.GetGPLinkFromResource(d) - err = gplink.ModifyGPLink(client, changes, isLocal) + err = gplink.ModifyGPLink(client, changes, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("while modifying GPLink with id %q: %s", d.Id(), err) } @@ -136,6 +139,7 @@ func resourceADGPLinkUpdate(d *schema.ResourceData, meta interface{}) error { func resourceADGPLinkDelete(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -143,7 +147,7 @@ func resourceADGPLinkDelete(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) gplink := winrmhelper.GetGPLinkFromResource(d) - err = gplink.RemoveGPLink(client, isLocal) + err = gplink.RemoveGPLink(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("while deleting resource with ID %q: %s", d.Id(), err) } diff --git a/ad/resource_ad_gpo.go b/ad/resource_ad_gpo.go index e1c1835c..d8c35316 100644 --- a/ad/resource_ad_gpo.go +++ b/ad/resource_ad_gpo.go @@ -55,6 +55,7 @@ func resourceADGPO() *schema.Resource { func resourceADGPOCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() g := winrmhelper.GetGPOFromResource(d) client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { @@ -62,7 +63,7 @@ func resourceADGPOCreate(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - guid, err := g.NewGPO(client, isLocal) + guid, err := g.NewGPO(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -75,13 +76,14 @@ func resourceADGPORead(d *schema.ResourceData, meta interface{}) error { return nil } isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err } defer meta.(ProviderConf).ReleaseWinRMClient(client) - g, err := winrmhelper.GetGPOFromHost(client, "", d.Id(), isLocal) + g, err := winrmhelper.GetGPOFromHost(client, "", d.Id(), isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "GpoWithNameNotFound") || strings.Contains(err.Error(), "GpoWithIdNotFound") { d.SetId("") @@ -99,6 +101,7 @@ func resourceADGPORead(d *schema.ResourceData, meta interface{}) error { func resourceADGPOUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -106,7 +109,7 @@ func resourceADGPOUpdate(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) g := winrmhelper.GetGPOFromResource(d) - _, err = g.UpdateGPO(client, d, isLocal) + _, err = g.UpdateGPO(client, d, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -115,6 +118,7 @@ func resourceADGPOUpdate(d *schema.ResourceData, meta interface{}) error { func resourceADGPODelete(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -122,7 +126,7 @@ func resourceADGPODelete(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) g := winrmhelper.GetGPOFromResource(d) - err = g.DeleteGPO(client, isLocal) + err = g.DeleteGPO(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } diff --git a/ad/resource_ad_gpo_security.go b/ad/resource_ad_gpo_security.go index 8246fdd1..53f2651d 100644 --- a/ad/resource_ad_gpo_security.go +++ b/ad/resource_ad_gpo_security.go @@ -30,6 +30,7 @@ func resourceADGPOSecurity() *schema.Resource { func resourceADGPOSecurityCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() winrmClient, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -54,19 +55,19 @@ func resourceADGPOSecurityCreate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error while generating ini file from resource data: %s", err) } - gpo, err := winrmhelper.GetGPOFromHost(winrmClient, "", guid, isLocal) + gpo, err := winrmhelper.GetGPOFromHost(winrmClient, "", guid, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } - err = winrmhelper.UploadSecIni(winrmClient, winrmCPClient, gpo, iniFile, isLocal) + err = winrmhelper.UploadSecIni(winrmClient, winrmCPClient, gpo, iniFile, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } // GUIDs for security settings are defined here: // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpsb/55bb803e-b35f-4ce8-b558-4c1e92ad77a4 - err = winrmhelper.SetMachineExtensionNames(winrmClient, gpo.DN, "[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]", isLocal) + err = winrmhelper.SetMachineExtensionNames(winrmClient, gpo.DN, "[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]", isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -78,6 +79,7 @@ func resourceADGPOSecurityCreate(d *schema.ResourceData, meta interface{}) error func resourceADGPOSecurityRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -91,7 +93,7 @@ func resourceADGPOSecurityRead(d *schema.ResourceData, meta interface{}) error { } guid := toks[0] - gpo, err := winrmhelper.GetGPOFromHost(client, "", guid, isLocal) + gpo, err := winrmhelper.GetGPOFromHost(client, "", guid, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "NotFound") { log.Printf("[DEBUG] GPO with guid %q not found", guid) @@ -102,7 +104,7 @@ func resourceADGPOSecurityRead(d *schema.ResourceData, meta interface{}) error { } _ = d.Set("gpo_container", guid) - hostSecIni, err := winrmhelper.GetSecIniFromHost(client, gpo, isLocal) + hostSecIni, err := winrmhelper.GetSecIniFromHost(client, gpo, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "ItemNotFoundException") { log.Printf("[DEBUG] inf file not found, marking resource as gone") @@ -118,6 +120,7 @@ func resourceADGPOSecurityRead(d *schema.ResourceData, meta interface{}) error { func resourceADGPOSecurityUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() winrmClient, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -138,7 +141,7 @@ func resourceADGPOSecurityUpdate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Cannot parse GUID %q: %s", guid, err) } - gpo, err := winrmhelper.GetGPOFromHost(winrmClient, "", guid, isLocal) + gpo, err := winrmhelper.GetGPOFromHost(winrmClient, "", guid, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while retrieving GPO with guid %q: %s", guid, err) } @@ -155,7 +158,7 @@ func resourceADGPOSecurityUpdate(d *schema.ResourceData, meta interface{}) error } iniSum := sha256.Sum256(iniBuf.Bytes()) - hostSecIniBytes, err := winrmhelper.GetSecIniContents(winrmClient, gpo, isLocal) + hostSecIniBytes, err := winrmhelper.GetSecIniContents(winrmClient, gpo, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while retrieving security settings contents for GPO with guid %q: %s", guid, err) } @@ -163,7 +166,7 @@ func resourceADGPOSecurityUpdate(d *schema.ResourceData, meta interface{}) error hostSum := sha256.Sum256(hostSecIniBytes) if iniSum != hostSum { - err = winrmhelper.UploadSecIni(winrmClient, winrmCPClient, gpo, iniFile, isLocal) + err = winrmhelper.UploadSecIni(winrmClient, winrmCPClient, gpo, iniFile, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while uploading security settings file for GPO with guid %q: %s", guid, err) } @@ -174,6 +177,7 @@ func resourceADGPOSecurityUpdate(d *schema.ResourceData, meta interface{}) error func resourceADGPOSecurityDelete(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() winrmClient, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -191,12 +195,12 @@ func resourceADGPOSecurityDelete(d *schema.ResourceData, meta interface{}) error } guid := toks[0] - gpo, err := winrmhelper.GetGPOFromHost(winrmClient, "", guid, isLocal) + gpo, err := winrmhelper.GetGPOFromHost(winrmClient, "", guid, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while retrieving GPO with guid %q: %s", guid, err) } - err = winrmhelper.RemoveSecIni(winrmClient, winrmCPClient, gpo, isLocal) + err = winrmhelper.RemoveSecIni(winrmClient, winrmCPClient, gpo, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("error while removing security settings INF file for GPO with guid %q: %s", guid, err) } diff --git a/ad/resource_ad_group.go b/ad/resource_ad_group.go index c820bde1..c9e8d66d 100644 --- a/ad/resource_ad_group.go +++ b/ad/resource_ad_group.go @@ -67,6 +67,7 @@ func resourceADGroup() *schema.Resource { func resourceADGroupCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() u := winrmhelper.GetGroupFromResource(d) client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { @@ -74,7 +75,8 @@ func resourceADGroupCreate(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - guid, err := u.AddGroup(client, isLocal) + guid, err := u.AddGroup(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) + if err != nil { return err } @@ -84,6 +86,7 @@ func resourceADGroupCreate(d *schema.ResourceData, meta interface{}) error { func resourceADGroupRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() log.Printf("Reading ad_Group resource for group with GUID: %q", d.Id()) client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { @@ -91,7 +94,7 @@ func resourceADGroupRead(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - g, err := winrmhelper.GetGroupFromHost(client, d.Id(), isLocal) + g, err := winrmhelper.GetGroupFromHost(client, d.Id(), isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "ADIdentityNotFoundException") { d.SetId("") @@ -116,6 +119,7 @@ func resourceADGroupRead(d *schema.ResourceData, meta interface{}) error { func resourceADGroupUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() g := winrmhelper.GetGroupFromResource(d) client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { @@ -123,7 +127,7 @@ func resourceADGroupUpdate(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - err = g.ModifyGroup(d, client, isLocal) + err = g.ModifyGroup(d, client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -132,20 +136,21 @@ func resourceADGroupUpdate(d *schema.ResourceData, meta interface{}) error { func resourceADGroupDelete(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() conn, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err } defer meta.(ProviderConf).ReleaseWinRMClient(conn) - g, err := winrmhelper.GetGroupFromHost(conn, d.Id(), isLocal) + g, err := winrmhelper.GetGroupFromHost(conn, d.Id(), isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "ADIdentityNotFoundException") { return nil } return err } - err = g.DeleteGroup(conn, isLocal) + err = g.DeleteGroup(conn, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("while deleting group: %s", err) } diff --git a/ad/resource_ad_group_membership.go b/ad/resource_ad_group_membership.go index ea2c73ea..bd610d04 100644 --- a/ad/resource_ad_group_membership.go +++ b/ad/resource_ad_group_membership.go @@ -39,6 +39,7 @@ func resourceADGroupMembership() *schema.Resource { func resourceADGroupMembershipRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -47,7 +48,7 @@ func resourceADGroupMembershipRead(d *schema.ResourceData, meta interface{}) err toks := strings.Split(d.Id(), "_") - gm, err := winrmhelper.NewGroupMembershipFromHost(client, toks[0], isLocal) + gm, err := winrmhelper.NewGroupMembershipFromHost(client, toks[0], isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -63,6 +64,7 @@ func resourceADGroupMembershipRead(d *schema.ResourceData, meta interface{}) err func resourceADGroupMembershipCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -74,7 +76,7 @@ func resourceADGroupMembershipCreate(d *schema.ResourceData, meta interface{}) e return err } - err = gm.Create(client, isLocal) + err = gm.Create(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -92,6 +94,7 @@ func resourceADGroupMembershipCreate(d *schema.ResourceData, meta interface{}) e func resourceADGroupMembershipUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -103,7 +106,7 @@ func resourceADGroupMembershipUpdate(d *schema.ResourceData, meta interface{}) e return err } - err = gm.Update(client, gm.GroupMembers, isLocal) + err = gm.Update(client, gm.GroupMembers, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -113,6 +116,7 @@ func resourceADGroupMembershipUpdate(d *schema.ResourceData, meta interface{}) e func resourceADGroupMembershipDelete(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -124,7 +128,7 @@ func resourceADGroupMembershipDelete(d *schema.ResourceData, meta interface{}) e return err } - err = gm.Delete(client, isLocal) + err = gm.Delete(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } diff --git a/ad/resource_ad_ou.go b/ad/resource_ad_ou.go index a8177a81..83015130 100644 --- a/ad/resource_ad_ou.go +++ b/ad/resource_ad_ou.go @@ -59,6 +59,7 @@ func resourceADOURead(d *schema.ResourceData, meta interface{}) error { return nil } isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { @@ -66,7 +67,7 @@ func resourceADOURead(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - ou, err := winrmhelper.NewOrgUnitFromHost(client, d.Id(), "", "", isLocal) + ou, err := winrmhelper.NewOrgUnitFromHost(client, d.Id(), "", "", isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "ObjectNotFound") { // Resource no longer exists @@ -88,6 +89,7 @@ func resourceADOURead(d *schema.ResourceData, meta interface{}) error { func resourceADOUCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -95,7 +97,7 @@ func resourceADOUCreate(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) ou := winrmhelper.NewOrgUnitFromResource(d) - guid, err := ou.Create(client, isLocal) + guid, err := ou.Create(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -106,6 +108,7 @@ func resourceADOUCreate(d *schema.ResourceData, meta interface{}) error { func resourceADOUUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -122,7 +125,7 @@ func resourceADOUUpdate(d *schema.ResourceData, meta interface{}) error { } } - err = ou.Update(client, changes, isLocal) + err = ou.Update(client, changes, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -131,6 +134,7 @@ func resourceADOUUpdate(d *schema.ResourceData, meta interface{}) error { func resourceADOUDelete(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -138,7 +142,7 @@ func resourceADOUDelete(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) ou := winrmhelper.NewOrgUnitFromResource(d) - err = ou.Delete(client, isLocal) + err = ou.Delete(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } diff --git a/ad/resource_ad_user.go b/ad/resource_ad_user.go index e68381dd..74f98db6 100644 --- a/ad/resource_ad_user.go +++ b/ad/resource_ad_user.go @@ -252,6 +252,7 @@ func suppressJsonDiff(k, old, new string, d *schema.ResourceData) bool { func resourceADUserCreate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() u, err := winrmhelper.GetUserFromResource(d) if err != nil { return fmt.Errorf("while building a User struct from resource data: %s", err) @@ -262,7 +263,7 @@ func resourceADUserCreate(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - guid, err := u.NewUser(client, isLocal) + guid, err := u.NewUser(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -286,6 +287,7 @@ func resourceADUserCreate(d *schema.ResourceData, meta interface{}) error { func resourceADUserRead(d *schema.ResourceData, meta interface{}) error { log.Printf("Reading ad_user resource for user with guid: %q", d.Id()) isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err @@ -298,7 +300,7 @@ func resourceADUserRead(d *schema.ResourceData, meta interface{}) error { return err } - u, err := winrmhelper.GetUserFromHost(client, d.Id(), caKeys, isLocal) + u, err := winrmhelper.GetUserFromHost(client, d.Id(), caKeys, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "ADIdentityNotFoundException") { d.SetId("") @@ -361,6 +363,7 @@ func resourceADUserRead(d *schema.ResourceData, meta interface{}) error { func resourceADUserUpdate(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() u, err := winrmhelper.GetUserFromResource(d) if err != nil { return err @@ -372,7 +375,7 @@ func resourceADUserUpdate(d *schema.ResourceData, meta interface{}) error { } defer meta.(ProviderConf).ReleaseWinRMClient(client) - err = u.ModifyUser(d, client, isLocal) + err = u.ModifyUser(d, client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return err } @@ -381,20 +384,21 @@ func resourceADUserUpdate(d *schema.ResourceData, meta interface{}) error { func resourceADUserDelete(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() + isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { return err } defer meta.(ProviderConf).ReleaseWinRMClient(client) - u, err := winrmhelper.GetUserFromHost(client, d.Id(), nil, isLocal) + u, err := winrmhelper.GetUserFromHost(client, d.Id(), nil, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { if strings.Contains(err.Error(), "ADIdentityNotFoundException") { return nil } return fmt.Errorf("while retrieving user data from host: %s", err) } - err = u.DeleteUser(client, isLocal) + err = u.DeleteUser(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) if err != nil { return fmt.Errorf("while deleting user: %s", err) } diff --git a/docs/index.md b/docs/index.md index 6cd9fb22..2f9c900b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -120,6 +120,20 @@ provider "ad" { winrm_username = "" winrm_password = "" } + +// remote using Kerberos authentication with krb5.conf file located in module when remote is not a Domain Controller +provider "ad" { + winrm_hostname = "10.0.0.1" + winrm_username = var.username + winrm_password = var.password + krb_realm = "YOURDOMAIN.COM" + krb_conf = "${path.module}/krb5.conf" + krb_spn = "winserver1" + winrm_insecure = true + winrm_port = 5986 + winrm_proto = "https" + winrm_pass_credentials = true +} ``` ## Schema @@ -139,3 +153,4 @@ provider "ad" { - **winrm_port** (Number, Optional) The port WinRM is listening for connections. (default: 5985, environment variable: AD_PORT) - **winrm_proto** (String, Optional) The WinRM protocol we will use. (default: http, environment variable: AD_PROTO) - **winrm_use_ntlm** (Boolean, Optional) Use NTLM authentication. (default: false, environment variable: AD_WINRM_USE_NTLM) +- **winrm_pass_credentials** (Boolean, Optional) Pass credentials in WinRM session to create a System.Management.Automation.PSCredential. (default: false, environment variable: AD_WINRM_PASS_CREDENTIALS) diff --git a/go.mod b/go.mod index 610c38f2..059420c2 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.15 require ( github.com/dylanmei/iso8601 v0.1.0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/hashicorp/go-uuid v1.0.2 github.com/hashicorp/terraform-plugin-sdk/v2 v2.5.0 github.com/jcmturner/gokrb5/v8 v8.4.2 @@ -13,5 +14,6 @@ require ( github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db github.com/smartystreets/goconvey v1.6.4 // indirect golang.org/x/text v0.3.3 + google.golang.org/appengine v1.6.6 // indirect gopkg.in/ini.v1 v1.55.0 ) From b775d4fac7f60b8dbeb8d83dc36862818a9155c3 Mon Sep 17 00:00:00 2001 From: Axton Grams Date: Wed, 5 May 2021 09:36:30 -0400 Subject: [PATCH 2/4] removed unnecessary whitespace changes and var declarations --- ad/data_source_ad_user.go | 1 - ad/internal/winrmhelper/winrm_group.go | 12 ++---------- ad/internal/winrmhelper/winrm_helper.go | 2 +- ad/resource_ad_group.go | 1 - 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/ad/data_source_ad_user.go b/ad/data_source_ad_user.go index 203ebe1e..13a2dd16 100644 --- a/ad/data_source_ad_user.go +++ b/ad/data_source_ad_user.go @@ -190,7 +190,6 @@ func dataSourceADUser() *schema.Resource { func dataSourceADUserRead(d *schema.ResourceData, meta interface{}) error { isLocal := meta.(ProviderConf).isConnectionTypeLocal() isPassCredentialsEnabled := meta.(ProviderConf).isPassCredentialsEnabled() - userID := d.Get("user_id").(string) client, err := meta.(ProviderConf).AcquireWinRMClient() if err != nil { diff --git a/ad/internal/winrmhelper/winrm_group.go b/ad/internal/winrmhelper/winrm_group.go index c389b9be..e3c9d716 100644 --- a/ad/internal/winrmhelper/winrm_group.go +++ b/ad/internal/winrmhelper/winrm_group.go @@ -38,11 +38,7 @@ func (g *Group) AddGroup(client *winrm.Client, execLocally bool, passCredentials cmds = append(cmds, fmt.Sprintf("-Description %q", g.Description)) } - var result *WinRMResult - var err error - - result, err = RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) - + result, err := RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) if err != nil { return "", err } @@ -158,11 +154,7 @@ func GetGroupFromResource(d *schema.ResourceData) *Group { // retrieved from the AD Controller. func GetGroupFromHost(client *winrm.Client, guid string, execLocally bool, passCredentials bool, username string, password string) (*Group, error) { cmd := fmt.Sprintf("Get-ADGroup -identity %q -properties *", guid) - - var result *WinRMResult - var err error - - result, err = RunWinRMCommand(client, []string{cmd}, true, false, execLocally, passCredentials, username, password) + result, err := RunWinRMCommand(client, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { return nil, err diff --git a/ad/internal/winrmhelper/winrm_helper.go b/ad/internal/winrmhelper/winrm_helper.go index 69f65938..a28178c6 100644 --- a/ad/internal/winrmhelper/winrm_helper.go +++ b/ad/internal/winrmhelper/winrm_helper.go @@ -124,7 +124,7 @@ func (p *PowerShell) ExecutePScmd(args ...string) (stdout string, stderr string, return } -// RunWinRMCommandWithCreds will run a powershell command and return the stdout and stderr +// RunWinRMCommand will run a powershell command and return the stdout and stderr // The output is converted to JSON if the json patameter is set to true. func RunWinRMCommand(conn *winrm.Client, cmds []string, json bool, forceArray bool, execLocally bool, passCredentials bool, username string, password string) (*WinRMResult, error) { if passCredentials { diff --git a/ad/resource_ad_group.go b/ad/resource_ad_group.go index c9e8d66d..0f45c886 100644 --- a/ad/resource_ad_group.go +++ b/ad/resource_ad_group.go @@ -76,7 +76,6 @@ func resourceADGroupCreate(d *schema.ResourceData, meta interface{}) error { defer meta.(ProviderConf).ReleaseWinRMClient(client) guid, err := u.AddGroup(client, isLocal, isPassCredentialsEnabled, meta.(ProviderConf).Configuration.WinRMUsername, meta.(ProviderConf).Configuration.WinRMPassword) - if err != nil { return err } From dc80034c2df92e88c817edebe4526675558b6d62 Mon Sep 17 00:00:00 2001 From: Axton Grams Date: Wed, 5 May 2021 10:57:34 -0400 Subject: [PATCH 3/4] removed redundant function declaration types --- ad/internal/winrmhelper/winrm_computer.go | 8 +++---- ad/internal/winrmhelper/winrm_gplink.go | 8 +++---- ad/internal/winrmhelper/winrm_gpo.go | 24 +++++++++---------- ad/internal/winrmhelper/winrm_group.go | 8 +++---- .../winrmhelper/winrm_group_membership.go | 16 ++++++------- ad/internal/winrmhelper/winrm_helper.go | 4 ++-- ad/internal/winrmhelper/winrm_ou.go | 8 +++---- ad/internal/winrmhelper/winrm_sec.go | 8 +++---- ad/internal/winrmhelper/winrm_user.go | 6 ++--- 9 files changed, 45 insertions(+), 45 deletions(-) diff --git a/ad/internal/winrmhelper/winrm_computer.go b/ad/internal/winrmhelper/winrm_computer.go index daecea8f..60f0e684 100644 --- a/ad/internal/winrmhelper/winrm_computer.go +++ b/ad/internal/winrmhelper/winrm_computer.go @@ -35,7 +35,7 @@ func NewComputerFromResource(d *schema.ResourceData) *Computer { // NewComputerFromHost return a new Machine struct populated from data we get // from the domain controller -func NewComputerFromHost(conn *winrm.Client, identity string, execLocally bool, passCredentials bool, username string, password string) (*Computer, error) { +func NewComputerFromHost(conn *winrm.Client, identity string, execLocally, passCredentials bool, username, password string) (*Computer, error) { cmd := fmt.Sprintf("Get-ADComputer -Identity %q -Properties *", identity) result, err := RunWinRMCommand(conn, []string{cmd}, true, false, execLocally, passCredentials, username, password) if err != nil { @@ -55,7 +55,7 @@ func NewComputerFromHost(conn *winrm.Client, identity string, execLocally bool, } // Create creates a new Computer object in the AD tree -func (m *Computer) Create(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (m *Computer) Create(conn *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { if m.Name == "" { return "", fmt.Errorf("Computer.Create: missing name variable") } @@ -90,7 +90,7 @@ func (m *Computer) Create(conn *winrm.Client, execLocally bool, passCredentials } // Update updates an existing Computer objects in the AD tree -func (m *Computer) Update(conn *winrm.Client, changes map[string]interface{}, execLocally bool, passCredentials bool, username string, password string) error { +func (m *Computer) Update(conn *winrm.Client, changes map[string]interface{}, execLocally, passCredentials bool, username, password string) error { if m.GUID == "" { return fmt.Errorf("cannot update computer object with name %q, guid is not set", m.Name) } @@ -126,7 +126,7 @@ func (m *Computer) Update(conn *winrm.Client, changes map[string]interface{}, ex } // Delete deletes an existing Computer objects from the AD tree -func (m *Computer) Delete(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (m *Computer) Delete(conn *winrm.Client, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf("Remove-ADComputer -confirm:$false -Identity %q", m.GUID) result, err := RunWinRMCommand(conn, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { diff --git a/ad/internal/winrmhelper/winrm_gplink.go b/ad/internal/winrmhelper/winrm_gplink.go index bc8a7907..6a8c6a06 100644 --- a/ad/internal/winrmhelper/winrm_gplink.go +++ b/ad/internal/winrmhelper/winrm_gplink.go @@ -23,7 +23,7 @@ type GPLink struct { } //NewGPLink creates a link between a GPO and an AD object -func (g *GPLink) NewGPLink(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (g *GPLink) NewGPLink(client *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { log.Printf("[DEBUG] Creating new user") enforced := "No" if g.Enforced { @@ -71,7 +71,7 @@ func (g *GPLink) NewGPLink(client *winrm.Client, execLocally bool, passCredentia } //ModifyGPLink changes a GPO link -func (g *GPLink) ModifyGPLink(client *winrm.Client, changes map[string]interface{}, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPLink) ModifyGPLink(client *winrm.Client, changes map[string]interface{}, execLocally, passCredentials bool, username, password string) error { cmds := []string{fmt.Sprintf("Set-GPLink -guid %q -target %q", g.GPOGuid, g.Target)} keyMap := map[string]string{ "enforced": "Enforced", @@ -108,7 +108,7 @@ func (g *GPLink) ModifyGPLink(client *winrm.Client, changes map[string]interface } //RemoveGPLink deletes a link between a GPO and an AD object -func (g *GPLink) RemoveGPLink(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPLink) RemoveGPLink(client *winrm.Client, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf("Remove-GPlink -Guid %q -Target %q", g.GPOGuid, g.Target) _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -136,7 +136,7 @@ func GetGPLinkFromResource(d *schema.ResourceData) *GPLink { //GetGPLinkFromHost returns a GPLink struct populated with data retrieved from the //Domain Controller -func GetGPLinkFromHost(client *winrm.Client, gpoGUID, containerGUID string, execLocally bool, passCredentials bool, username string, password string) (*GPLink, error) { +func GetGPLinkFromHost(client *winrm.Client, gpoGUID, containerGUID string, execLocally, passCredentials bool, username, password string) (*GPLink, error) { cmds := []string{fmt.Sprintf("Get-ADObject -filter {ObjectGUID -eq %q} -properties gplink", containerGUID)} result, err := RunWinRMCommand(client, cmds, true, false, execLocally, passCredentials, username, password) if err != nil { diff --git a/ad/internal/winrmhelper/winrm_gpo.go b/ad/internal/winrmhelper/winrm_gpo.go index 262ee830..a650ef84 100644 --- a/ad/internal/winrmhelper/winrm_gpo.go +++ b/ad/internal/winrmhelper/winrm_gpo.go @@ -66,7 +66,7 @@ func unmarshallGPO(input []byte) (*GPO, error) { } // GetGPOFromHost returns a GPO structure populated by data from the DC server -func GetGPOFromHost(conn *winrm.Client, name, guid string, execLocally bool, passCredentials bool, username string, password string) (*GPO, error) { +func GetGPOFromHost(conn *winrm.Client, name, guid string, execLocally, passCredentials bool, username, password string) (*GPO, error) { start := time.Now().Unix() var cmd string if name != "" { @@ -120,7 +120,7 @@ func GetGPOFromResource(d *schema.ResourceData) *GPO { } // Rename renames a GPO to the given name -func (g *GPO) Rename(client *winrm.Client, target string, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPO) Rename(client *winrm.Client, target string, execLocally, passCredentials bool, username, password string) error { if g.ID == "" { return fmt.Errorf("gpo guid required") } @@ -139,7 +139,7 @@ func (g *GPO) Rename(client *winrm.Client, target string, execLocally bool, pass } //ChangeStatus Changes the status of a GPO -func (g *GPO) ChangeStatus(client *winrm.Client, status string, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPO) ChangeStatus(client *winrm.Client, status string, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf(`(%s).GpoStatus = "%s"`, getGPOCmdByGUID(g.ID), status) result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -154,7 +154,7 @@ func (g *GPO) ChangeStatus(client *winrm.Client, status string, execLocally bool } // NewGPO uses Powershell over WinRM to create a script -func (g *GPO) NewGPO(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (g *GPO) NewGPO(client *winrm.Client, execLocally, passCredentials bool, username string, password string) (string, error) { if g.Name == "" { return "", fmt.Errorf("gpo name required") @@ -189,7 +189,7 @@ func (g *GPO) NewGPO(client *winrm.Client, execLocally bool, passCredentials boo } // DeleteGPO delete the GPO container -func (g *GPO) DeleteGPO(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPO) DeleteGPO(client *winrm.Client, execLocally bool, passCredentials bool, username, password string) error { cmd := fmt.Sprintf("Remove-GPO -Name %s -Domain %s", g.Name, g.Domain) _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -203,7 +203,7 @@ func (g *GPO) DeleteGPO(client *winrm.Client, execLocally bool, passCredentials } // UpdateGPO updates the GPO container -func (g *GPO) UpdateGPO(client *winrm.Client, d *schema.ResourceData, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (g *GPO) UpdateGPO(client *winrm.Client, d *schema.ResourceData, execLocally, passCredentials bool, username, password string) (string, error) { if d.HasChange("name") { err := g.Rename(client, SanitiseTFInput(d, "name"), execLocally, passCredentials, username, password) if err != nil { @@ -223,7 +223,7 @@ func (g *GPO) UpdateGPO(client *winrm.Client, d *schema.ResourceData, execLocall // getGPOFilePath retrieves the AD Object of a GPO via powershell and returns the gPCFileSysPath // property. This property points at the UNC that the GPO stores its configuration. We use the output // of this function as well as GetsysVolPath to construct the GPO path on the DC's filesystem. -func (g *GPO) getGPOFilePath(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (g *GPO) getGPOFilePath(client *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { cmd := fmt.Sprintf("(Get-ADObject -LDAPFilter '(&(objectClass=groupPolicyContainer)(cn={%s}))' -Properties gPCFilesysPath).gPCFilesysPath", g.ID) result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -237,7 +237,7 @@ func (g *GPO) getGPOFilePath(client *winrm.Client, execLocally bool, passCredent //getSysVolPath returns the local path for the SYSVOL share on a Domain Controller. The combination of this // and the value we get from getGPOFilePath is used to construct the GPO path on the DC's filesystem. -func getSysVolPath(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func getSysVolPath(client *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { cmd := "(Get-SmbShare sysvol).path" result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -251,7 +251,7 @@ func getSysVolPath(client *winrm.Client, execLocally bool, passCredentials bool, // GetGPOBasePath returns the base path of a GPO on the DC. All GPO related files go // in that location. -func (g *GPO) loadGPOBasePath(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (g *GPO) loadGPOBasePath(client *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { gpoPath, err := g.getGPOFilePath(client, execLocally, passCredentials, username, password) if err != nil { return "", err @@ -285,7 +285,7 @@ func (g *GPO) loadGPOVersions(client *winrm.Client, gpoPath string) error { } // SetADGPOVersions updates AD with the given versions for a GPO -func (g *GPO) SetADGPOVersions(client *winrm.Client, gpoVersion uint32, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPO) SetADGPOVersions(client *winrm.Client, gpoVersion uint32, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf("$o=(Get-ADObject -LDAPFilter '(&(objectClass=groupPolicyContainer)(cn={%s}))' -Properties *);$o.VersionNumber=%d;Set-AdObject -Instance $o", g.ID, gpoVersion) result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -321,7 +321,7 @@ func (g *GPO) SetINIGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, g } // SetGPOVersions updates gpt.ini on the DC with the given values for user and computer version of a GPO. -func (g *GPO) SetGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, userVersion, computerVersion uint16, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPO) SetGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, userVersion, computerVersion uint16, execLocally, passCredentials bool, username, password string) error { outBuf := make([]byte, 4) binary.LittleEndian.PutUint16(outBuf[:2], computerVersion) binary.LittleEndian.PutUint16(outBuf[2:], userVersion) @@ -339,7 +339,7 @@ func (g *GPO) SetGPOVersions(client *winrm.Client, cpConn *winrmcp.Winrmcp, user return nil } -func (g *GPO) loadGPTIni(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GPO) loadGPTIni(client *winrm.Client, execLocally, passCredentials bool, username, password string) error { gptPath := fmt.Sprintf("%s\\gpt.ini", g.basePath) log.Printf("[DEBUG] Getting GPT ini from %s", gptPath) cmd := fmt.Sprintf(`Get-Content "%s"`, gptPath) diff --git a/ad/internal/winrmhelper/winrm_group.go b/ad/internal/winrmhelper/winrm_group.go index e3c9d716..00f5e139 100644 --- a/ad/internal/winrmhelper/winrm_group.go +++ b/ad/internal/winrmhelper/winrm_group.go @@ -26,7 +26,7 @@ type Group struct { } // AddGroup creates a new group -func (g *Group) AddGroup(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (g *Group) AddGroup(client *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { log.Printf("[DEBUG] Adding group with name %q", g.Name) cmds := []string{fmt.Sprintf("New-ADGroup -Passthru -Name %q -GroupScope %q -GroupCategory %q -Path %q", g.Name, g.Scope, g.Category, g.Container)} @@ -60,7 +60,7 @@ func (g *Group) AddGroup(client *winrm.Client, execLocally bool, passCredentials } // ModifyGroup updates an existing group -func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLocally, passCredentials bool, username, password string) error { KeyMap := map[string]string{ "sam_account_name": "SamAccountName", "scope": "GroupScope", @@ -122,7 +122,7 @@ func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLo } // DeleteGroup removes a group -func (g *Group) DeleteGroup(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (g *Group) DeleteGroup(client *winrm.Client, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf("Remove-ADGroup -Identity %s -Confirm:$false", g.GUID) _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -152,7 +152,7 @@ func GetGroupFromResource(d *schema.ResourceData) *Group { // GetGroupFromHost returns a Group struct based on data // retrieved from the AD Controller. -func GetGroupFromHost(client *winrm.Client, guid string, execLocally bool, passCredentials bool, username string, password string) (*Group, error) { +func GetGroupFromHost(client *winrm.Client, guid string, execLocally, passCredentials bool, username, password string) (*Group, error) { cmd := fmt.Sprintf("Get-ADGroup -identity %q -properties *", guid) result, err := RunWinRMCommand(client, []string{cmd}, true, false, execLocally, passCredentials, username, password) diff --git a/ad/internal/winrmhelper/winrm_group_membership.go b/ad/internal/winrmhelper/winrm_group_membership.go index 29f21e8a..0d29ae27 100644 --- a/ad/internal/winrmhelper/winrm_group_membership.go +++ b/ad/internal/winrmhelper/winrm_group_membership.go @@ -66,7 +66,7 @@ func getMembershipList(g []*GroupMember) string { return strings.Join(out, ",") } -func (g *GroupMembership) getGroupMembers(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) ([]*GroupMember, error) { +func (g *GroupMembership) getGroupMembers(client *winrm.Client, execLocally, passCredentials bool, username, password string) ([]*GroupMember, error) { cmd := fmt.Sprintf("Get-ADGroupMember -Identity %q", g.GroupGUID) result, err := RunWinRMCommand(client, []string{cmd}, true, true, execLocally, passCredentials, username, password) @@ -88,7 +88,7 @@ func (g *GroupMembership) getGroupMembers(client *winrm.Client, execLocally bool return gm, nil } -func (g *GroupMembership) bulkGroupMembersOp(client *winrm.Client, operation string, members []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GroupMembership) bulkGroupMembersOp(client *winrm.Client, operation string, members []*GroupMember, execLocally, passCredentials bool, username, password string) error { if len(members) == 0 { return nil } @@ -106,15 +106,15 @@ func (g *GroupMembership) bulkGroupMembersOp(client *winrm.Client, operation str return nil } -func (g *GroupMembership) addGroupMembers(client *winrm.Client, members []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GroupMembership) addGroupMembers(client *winrm.Client, members []*GroupMember, execLocally, passCredentials bool, username, password string) error { return g.bulkGroupMembersOp(client, "Add-ADGroupMember", members, execLocally, passCredentials, username, password) } -func (g *GroupMembership) removeGroupMembers(client *winrm.Client, members []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GroupMembership) removeGroupMembers(client *winrm.Client, members []*GroupMember, execLocally, passCredentials bool, username, password string) error { return g.bulkGroupMembersOp(client, "Remove-ADGroupMember", members, execLocally, passCredentials, username, password) } -func (g *GroupMembership) Update(client *winrm.Client, expected []*GroupMember, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GroupMembership) Update(client *winrm.Client, expected []*GroupMember, execLocally, passCredentials bool, username, password string) error { existing, err := g.getGroupMembers(client, execLocally, passCredentials, username, password) if err != nil { return err @@ -134,7 +134,7 @@ func (g *GroupMembership) Update(client *winrm.Client, expected []*GroupMember, return nil } -func (g *GroupMembership) Create(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GroupMembership) Create(client *winrm.Client, execLocally, passCredentials bool, username, password string) error { if len(g.GroupMembers) == 0 { return nil } @@ -151,7 +151,7 @@ func (g *GroupMembership) Create(client *winrm.Client, execLocally bool, passCre return nil } -func (g *GroupMembership) Delete(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (g *GroupMembership) Delete(client *winrm.Client, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf("Remove-ADGroupMember %q -Members (Get-ADGroupMember %q) -Confirm:$false", g.GroupGUID, g.GroupGUID) result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { @@ -162,7 +162,7 @@ func (g *GroupMembership) Delete(client *winrm.Client, execLocally bool, passCre return nil } -func NewGroupMembershipFromHost(client *winrm.Client, groupID string, execLocally bool, passCredentials bool, username string, password string) (*GroupMembership, error) { +func NewGroupMembershipFromHost(client *winrm.Client, groupID string, execLocally, passCredentials bool, username, password string) (*GroupMembership, error) { result := &GroupMembership{ GroupGUID: groupID, } diff --git a/ad/internal/winrmhelper/winrm_helper.go b/ad/internal/winrmhelper/winrm_helper.go index a28178c6..d8651392 100644 --- a/ad/internal/winrmhelper/winrm_helper.go +++ b/ad/internal/winrmhelper/winrm_helper.go @@ -126,7 +126,7 @@ func (p *PowerShell) ExecutePScmd(args ...string) (stdout string, stderr string, // RunWinRMCommand will run a powershell command and return the stdout and stderr // The output is converted to JSON if the json patameter is set to true. -func RunWinRMCommand(conn *winrm.Client, cmds []string, json bool, forceArray bool, execLocally bool, passCredentials bool, username string, password string) (*WinRMResult, error) { +func RunWinRMCommand(conn *winrm.Client, cmds []string, json, forceArray, execLocally, passCredentials bool, username, password string) (*WinRMResult, error) { if passCredentials { cmds = append(cmds, "-Credential $Credential") } @@ -234,7 +234,7 @@ func SanitiseString(key string) string { // SetMachineExtensionName will add the necessary GUIDs to the GPO's gPCMachineExtensionNames attribute. // These are required for the security settings part of a GPO to work. -func SetMachineExtensionNames(client *winrm.Client, gpoDN, value string, execLocally bool, passCredentials bool, username string, password string) error { +func SetMachineExtensionNames(client *winrm.Client, gpoDN, value string, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf(`Set-ADObject -Identity "%s" -Replace @{gPCMachineExtensionNames="%s"}`, gpoDN, value) result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { diff --git a/ad/internal/winrmhelper/winrm_ou.go b/ad/internal/winrmhelper/winrm_ou.go index 25766258..d39fb8d6 100644 --- a/ad/internal/winrmhelper/winrm_ou.go +++ b/ad/internal/winrmhelper/winrm_ou.go @@ -36,7 +36,7 @@ func NewOrgUnitFromResource(d *schema.ResourceData) *OrgUnit { // NewOrgUnitFromHost returns a new OrgUnit struct populated from data we get from // the domain controller -func NewOrgUnitFromHost(conn *winrm.Client, guid, name, path string, execLocally bool, passCredentials bool, username string, password string) (*OrgUnit, error) { +func NewOrgUnitFromHost(conn *winrm.Client, guid, name, path string, execLocally, passCredentials bool, username, password string) (*OrgUnit, error) { var cmd string if guid != "" { cmd = fmt.Sprintf("Get-ADObject -Properties * -Identity %q", guid) @@ -63,7 +63,7 @@ func NewOrgUnitFromHost(conn *winrm.Client, guid, name, path string, execLocally } // Create creates a new OU in the AD tree -func (o *OrgUnit) Create(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (o *OrgUnit) Create(conn *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { cmd := "New-ADOrganizationalUnit -Passthru" if o.Name == "" { @@ -97,7 +97,7 @@ func (o *OrgUnit) Create(conn *winrm.Client, execLocally bool, passCredentials b } // Update updates an existing OU in the AD tree -func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, execLocally bool, passCredentials bool, username string, password string) error { +func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, execLocally, passCredentials bool, username, password string) error { if o.DistinguishedName == "" { return fmt.Errorf("Cannot update OU with name %q, distiguished name is empty", o.Name) } @@ -151,7 +151,7 @@ func (o *OrgUnit) Update(conn *winrm.Client, changes map[string]interface{}, exe } // Delete deletes an existing OU from an AD tree -func (o *OrgUnit) Delete(conn *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (o *OrgUnit) Delete(conn *winrm.Client, execLocally, passCredentials bool, username, password string) error { if o.DistinguishedName == "" { return fmt.Errorf("Cannot remove OU with name %q, distiguished name is empty", o.Name) } diff --git a/ad/internal/winrmhelper/winrm_sec.go b/ad/internal/winrmhelper/winrm_sec.go index d4ea1b75..2a2fed1c 100644 --- a/ad/internal/winrmhelper/winrm_sec.go +++ b/ad/internal/winrmhelper/winrm_sec.go @@ -41,7 +41,7 @@ func GetSecIniFromResource(d *schema.ResourceData, schemaKeys map[string]*schema // GetSecIniContents returns a byte array with the contents of the INF file // encoded in UTF-8 (since we get the ouput via stdout). -func GetSecIniContents(client *winrm.Client, gpo *GPO, execLocally bool, passCredentials bool, username string, password string) ([]byte, error) { +func GetSecIniContents(client *winrm.Client, gpo *GPO, execLocally, passCredentials bool, username, password string) ([]byte, error) { gptPath := fmt.Sprintf("%s\\Machine\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf", gpo.basePath) log.Printf("[DEBUG] Getting security settings inf from %s", gptPath) @@ -59,7 +59,7 @@ func GetSecIniContents(client *winrm.Client, gpo *GPO, execLocally bool, passCre } // GetSecIniFromHost returns a struct representing the data retrieved from the host. -func GetSecIniFromHost(client *winrm.Client, gpo *GPO, execLocally bool, passCredentials bool, username string, password string) (*gposec.SecuritySettings, error) { +func GetSecIniFromHost(client *winrm.Client, gpo *GPO, execLocally, passCredentials bool, username, password string) (*gposec.SecuritySettings, error) { iniBytes, err := GetSecIniContents(client, gpo, execLocally, passCredentials, username, password) if err != nil { @@ -74,7 +74,7 @@ func GetSecIniFromHost(client *winrm.Client, gpo *GPO, execLocally bool, passCre // UploadSecIni uploads the security settings ini to the correct folder of a GPO and updates // the GPO's gpt.ini by incrementing the computer version by 1. -func UploadSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, iniFile *ini.File, execLocally bool, passCredentials bool, username string, password string) error { +func UploadSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, iniFile *ini.File, execLocally, passCredentials bool, username, password string) error { ini.LineBreak = "\r\n" buf := bytes.NewBuffer([]byte{}) iniLocation := fmt.Sprintf("%s\\Machine\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf", gpo.basePath) @@ -97,7 +97,7 @@ func UploadSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, iniFile // RemoveSecIni removes the ini file from the host and updates the GPO's gpt.ini by incrementing the // computer version by 1. -func RemoveSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, execLocally bool, passCredentials bool, username string, password string) error { +func RemoveSecIni(conn *winrm.Client, cpConn *winrmcp.Winrmcp, gpo *GPO, execLocally, passCredentials bool, username, password string) error { gptPath := fmt.Sprintf("%s\\Machine\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf", gpo.basePath) log.Printf("[DEBUG] Getting security settings inf from %s", gptPath) diff --git a/ad/internal/winrmhelper/winrm_user.go b/ad/internal/winrmhelper/winrm_user.go index ae1a12de..1a22919e 100644 --- a/ad/internal/winrmhelper/winrm_user.go +++ b/ad/internal/winrmhelper/winrm_user.go @@ -62,7 +62,7 @@ type User struct { } // NewUser creates the user by running the New-ADUser powershell command -func (u *User) NewUser(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) (string, error) { +func (u *User) NewUser(client *winrm.Client, execLocally, passCredentials bool, username, password string) (string, error) { if u.Username == "" { return "", fmt.Errorf("user principal name required") } @@ -234,7 +234,7 @@ func (u *User) NewUser(client *winrm.Client, execLocally bool, passCredentials b } // ModifyUser updates the AD user's details based on what's changed in the resource. -func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLocally, passCredentials bool, username, password string) error { log.Printf("Modifying user: %q", u.PrincipalName) strKeyMap := map[string]string{ "sam_account_name": "SamAccountName", @@ -412,7 +412,7 @@ func (u *User) ModifyUser(d *schema.ResourceData, client *winrm.Client, execLoca } //DeleteUser deletes an AD user by calling Remove-ADUser -func (u *User) DeleteUser(client *winrm.Client, execLocally bool, passCredentials bool, username string, password string) error { +func (u *User) DeleteUser(client *winrm.Client, execLocally, passCredentials bool, username, password string) error { cmd := fmt.Sprintf("Remove-ADUser -Identity %s -Confirm:$false", u.GUID) _, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { From 261f2018a899327e6e1bf9c34b43cf16c708621c Mon Sep 17 00:00:00 2001 From: Axton Grams Date: Mon, 10 May 2021 11:58:29 -0400 Subject: [PATCH 4/4] incorporating Pull Request #109 --- ad/internal/winrmhelper/winrm_group.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ad/internal/winrmhelper/winrm_group.go b/ad/internal/winrmhelper/winrm_group.go index 00f5e139..26a74333 100644 --- a/ad/internal/winrmhelper/winrm_group.go +++ b/ad/internal/winrmhelper/winrm_group.go @@ -94,8 +94,8 @@ func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLo } if d.HasChange("name") { - cmds := []string{"Rename-ADObject -Identity %q -NewName %q", g.GUID, d.Get("name").(string)} - result, err := RunWinRMCommand(client, cmds, false, false, execLocally, passCredentials, username, password) + cmds := fmt.Sprintf("Rename-ADObject -Identity %q -NewName %q", g.GUID, d.Get("name").(string)) + result, err := RunWinRMCommand(client, []string{cmds}, false, false, execLocally, passCredentials, username, password) if err != nil { return err } @@ -106,8 +106,8 @@ func (g *Group) ModifyGroup(d *schema.ResourceData, client *winrm.Client, execLo } if d.HasChange("container") { - cmds := []string{"Rename-ADObject -Identity %q -NewName %q", g.GUID, d.Get("name").(string)} - result, err := RunWinRMCommand(client, cmds, false, false, execLocally, passCredentials, username, password) + cmd := fmt.Sprintf("Move-ADObject -Identity %q -TargetPath %q", g.GUID, d.Get("container").(string)) + result, err := RunWinRMCommand(client, []string{cmd}, false, false, execLocally, passCredentials, username, password) if err != nil { return err }