| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | package activedir
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import (
 | 
					
						
							|  |  |  | 	"fmt"
 | 
					
						
							|  |  |  | 	"os/exec"
 | 
					
						
							|  |  |  | 	"strconv"
 | 
					
						
							|  |  |  | 	"strings"
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | 	"sync"
 | 
					
						
							| 
									
										
										
										
											2018-02-05 16:17:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/pkg/errors"
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | var checkPS sync.Once
 | 
					
						
							|  |  |  | var psAvailible = false
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | func (c *adProvider) getRecords(domainname string) ([]byte, error) {
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | 	// If we are using PowerShell, make sure it is enabled
 | 
					
						
							|  |  |  | 	// and then run the PS1 command to generate the adzonedump file.
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 	if !c.fake {
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | 		checkPS.Do(func() {
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 			psAvailible = c.isPowerShellReady()
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | 			if !psAvailible {
 | 
					
						
							|  |  |  | 				fmt.Printf("\n\n\n")
 | 
					
						
							|  |  |  | 				fmt.Printf("***********************************************\n")
 | 
					
						
							|  |  |  | 				fmt.Printf("PowerShell DnsServer module not installed.\n")
 | 
					
						
							|  |  |  | 				fmt.Printf("See http://social.technet.microsoft.com/wiki/contents/articles/2202.remote-server-administration-tools-rsat-for-windows-client-and-windows-server-dsforum2wiki.aspx\n")
 | 
					
						
							|  |  |  | 				fmt.Printf("***********************************************\n")
 | 
					
						
							|  |  |  | 				fmt.Printf("\n\n\n")
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 		})
 | 
					
						
							|  |  |  | 		if !psAvailible {
 | 
					
						
							| 
									
										
										
										
											2018-02-05 16:17:20 -05:00
										 |  |  | 			return nil, errors.Errorf("powershell module DnsServer not installed")
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 		_, err := c.powerShellExec(c.generatePowerShellZoneDump(domainname), true)
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 		if err != nil {
 | 
					
						
							|  |  |  | 			return []byte{}, err
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	// Return the contents of zone.*.json file instead.
 | 
					
						
							|  |  |  | 	return c.readZoneDump(domainname)
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | func (c *adProvider) isPowerShellReady() bool {
 | 
					
						
							|  |  |  | 	query, _ := c.powerShellExec(`(Get-Module -ListAvailable DnsServer) -ne $null`, true)
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	q, err := strconv.ParseBool(strings.TrimSpace(string(query)))
 | 
					
						
							|  |  |  | 	if err != nil {
 | 
					
						
							|  |  |  | 		return false
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	return q
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | func (c *adProvider) powerShellDoCommand(command string, shouldLog bool) error {
 | 
					
						
							|  |  |  | 	if c.fake {
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 		// If fake, just record the command.
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 		return c.powerShellRecord(command)
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 	_, err := c.powerShellExec(command, shouldLog)
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	return err
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | func (c *adProvider) powerShellExec(command string, shouldLog bool) ([]byte, error) {
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	// log it.
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 	err := c.logCommand(command)
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	if err != nil {
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | 		return nil, err
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Run it.
 | 
					
						
							|  |  |  | 	out, err := exec.Command("powershell", "-NoProfile", command).CombinedOutput()
 | 
					
						
							|  |  |  | 	if err != nil {
 | 
					
						
							|  |  |  | 		// If there was an error, log it.
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 		c.logErr(err)
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | 	if shouldLog {
 | 
					
						
							| 
									
										
										
										
											2017-09-13 10:00:41 -04:00
										 |  |  | 		err = c.logOutput(string(out))
 | 
					
						
							| 
									
										
										
										
											2017-04-13 10:19:51 -06:00
										 |  |  | 		if err != nil {
 | 
					
						
							|  |  |  | 			return []byte{}, err
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							| 
									
										
										
										
											2016-08-22 18:31:50 -06:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Return the result.
 | 
					
						
							|  |  |  | 	return out, err
 | 
					
						
							|  |  |  | }
 |