func authInit() { os.MkdirAll(path.Join(common.BaseDir, "auth"), 0755) err := os.RemoveAll(path.Join(common.BaseDir, "auth", "secure")) if err != nil { log.Printf("Failed to clean out the secure directory. %v\n", err) os.Exit(-1) } err = os.RemoveAll(path.Join(common.BaseDir, "auth", "user")) if err != nil { log.Printf("Failed to clean out the user directory. %v\n", err) os.Exit(-1) } os.MkdirAll(path.Join(common.BaseDir, "auth", "user"), 0755) os.MkdirAll(path.Join(common.BaseDir, "auth", "secure"), 0700) if common.System && platform.PlatformGet() == platform.Windows { err = common.Cacls(path.Join(common.BaseDir, "auth", "secure"), "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) os.Exit(-1) } err = common.Cacls(path.Join(common.BaseDir, "auth", "user"), "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Users:r", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls on auth user %v\n", err) os.Exit(-1) } } }
func (store *AuthStore) GetFile(user string) (string, string) { store.mutex.Lock() defer store.mutex.Unlock() var upath string passwd := store.user2pass[user] if passwd != "" { upath = store.getFinalFilename(user) } else { buffer := make([]byte, 33, 33) spath := store.getProtectedFilename(user) upath = store.getFinalFilename(user) file, err := os.OpenFile(spath, os.O_RDWR|os.O_CREATE, 0600) if err != nil { log.Printf("Error writing user auth file. %v\n", err) } else { _, err := rand.Read(buffer) if err != nil { log.Println("Error on random.", err) } passwd = base64.StdEncoding.EncodeToString(buffer) file.Write([]byte(passwd + "\n")) store.user2pass[user] = passwd file.Close() uid, err := strconv.Atoi(user) if err != nil { //FIXME } if common.System { switch platform.PlatformGet() { case platform.Windows: //TODO - remove??? NGT 2/19/2012 //err = common.Cacls(spath, "/p", "NT AUTHORITY\\SYSTEM:f", user + ":r", "BUILTIN\\Administrators:F") user = strings.TrimSpace(user) err = common.Cacls(spath, "/p", "NT AUTHORITY\\SYSTEM:f", user+":r", "BUILTIN\\Administrators:F") case platform.Linux: //FIXME validate username cmd := exec.Command("setfacl", "-m", "user:"******":r", spath) err = cmd.Run() case platform.Darwin: log.Panic("Darwin not yet supported") default: log.Panic("%v+ not yet supported", runtime.GOOS) } if err != nil { log.Printf("Error %v |%s|\n", err, user) return "", "" } } if platform.PlatformGet() == platform.Windows { err = os.Remove(upath) } err = os.Rename(spath, upath) if err != nil { log.Println("Error %v", err) } } } return upath, passwd }
func authHandle(w http.ResponseWriter, req *http.Request) { c := strings.Count(req.URL.Path, "/") l := len(req.URL.Path) if c == 2 || (c == 3 && req.URL.Path[l-1:l] == "/" && req.URL.Path[l-2:l-1] != "/") { ss := strings.Split(req.URL.Path, "/") user := ss[2] if user == "" { w.WriteHeader(http.StatusBadRequest) } else { switch platform.PlatformGet() { case platform.Windows: if strings.Index(user, ":") != -1 { w.WriteHeader(http.StatusBadRequest) } else { path, _ := authStore.GetFile(strings.ToLower(user)) w.Write([]byte(path + "\n")) } case platform.Linux: path, _ := authStore.GetFile(user) w.Write([]byte(path + "\n")) case platform.Darwin: log.Panic("Darwin not yet supported") default: log.Panic("%v+ not yet supported", runtime.GOOS) } } } else { w.WriteHeader(http.StatusBadRequest) } }
func (self *UserConfig) Save(filename string) error { j, err := json.Marshal(self) if err != nil { return err } buff := new(bytes.Buffer) json.Indent(buff, j, "", "\t") file, err := os.Create(filename + ".new") if err != nil { return err } _, err = file.Write(buff.Bytes()) if err != nil { return err } file.Close() if platform.PlatformGet() == platform.Windows { os.Remove(filename) } if err := os.Rename(filename+".new", filename); err != nil { log.Printf("Failed to rename %s, error %v", filename, err) return err } return nil }
func configInit() { t, err := template.ParseFiles(filepath.Join(common.UiDirGet(), "config.html")) if err != nil { log.Printf("config.html parse failed %v\n", err) return } else { configTemplate = t } configChannel = make(chan configRequest) ConfigRun() web.ServMux.Handle("/config/", http.RedirectHandler("/ui/config.html", http.StatusMovedPermanently)) web.ServMux.HandleFunc("/config/all/", configHandle) os.MkdirAll(filepath.Join(common.BaseDir, "config"), 0700) if common.System && platform.PlatformGet() == platform.Windows { err = common.Cacls(filepath.Join(common.BaseDir, "config"), "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) os.Exit(-1) } } processConfig() m.updatePaths(&allConfigs) }
func createDatabaseDir() { dir := common.StateDir os.MkdirAll(dir, 0700) if common.System && platform.PlatformGet() == platform.Windows { err := common.Cacls(dir, "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Administrators:F") if err != nil { log.Panic("Failed to run cacls %v\n", err) } } }
func userdInit() { userd = make(map[string]*rpc.Client) if System == false || platform.PlatformGet() != platform.Linux { var err error userd_fallback, err = userdSpawn("") if err != nil { log.Printf("Failed to get default userd. %v\n", err) os.Exit(1) } } }
func bundlerInit() { os.MkdirAll(filepath.Join(common.BaseDir, "bundles"), 0755) err := os.RemoveAll(filepath.Join(common.BaseDir, "bundles", "inprogress")) if err != nil { log.Printf("Failed to clean out the inprogress. %v\n", err) os.Exit(-1) } os.MkdirAll(filepath.Join(common.BaseDir, "bundles", "inprogress"), 0755) if common.System && platform.PlatformGet() == platform.Windows { err = common.Cacls(filepath.Join(common.BaseDir, "bundles", "inprogress"), "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Users:r", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) os.Exit(-1) } } }
func userdForUserGet(user string) (*rpc.Client, error) { if System && platform.PlatformGet() == platform.Linux { mutex.Lock() defer mutex.Unlock() if userd[user] != nil { return userd[user], nil } tmpuserd, err := userdSpawn(user) if err != nil { return nil, err } userd[user] = tmpuserd return tmpuserd, nil } if userd_fallback == nil { return nil, errors.New("Bad userd") } return userd_fallback, nil }
func credsInit() *CredsManager { cm := &CredsManager{} cm.userCreds = make(map[string]*pacificaauth.Auth) cm.outage = make(map[string]*time.Time) web.ServMux.HandleFunc("/passcreds/", func(w http.ResponseWriter, req *http.Request) { passcredsHandle(cm, w, req) }) web.ServMux.HandleFunc("/status/xml/", func(w http.ResponseWriter, req *http.Request) { statusXmlHandle(cm, w, req) }) os.MkdirAll(filepath.Join(common.BaseDir, "auth", "creds"), 0700) err := os.RemoveAll(filepath.Join(common.BaseDir, "auth", "tmpcreds")) if err != nil { log.Printf("Failed to clean out the tmpcreds directory. %v\n", err) os.Exit(-1) } os.MkdirAll(filepath.Join(common.BaseDir, "auth", "tmpcreds"), 0700) if common.System && platform.PlatformGet() == platform.Windows { err = common.Cacls(filepath.Join(common.BaseDir, "auth", "creds"), "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) os.Exit(-1) } err = common.Cacls(filepath.Join(common.BaseDir, "auth", "tmpcreds"), "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) os.Exit(-1) } } creds, err := filepath.Glob(filepath.Join(common.BaseDir, "auth", "creds", "*")) if err == nil { for _, credfile := range creds { user := common.FsDecodeUser(credfile) if user != "" { file, err := os.Open(credfile) if err == nil { auth := pacificaauth.NewAuth(file) if auth != nil { log.Printf("Found cred file. %v %v\n", credfile, user) cm.userCreds[user] = auth } } } } } return cm }
func Init() { log.Println("Common subsystem init.") if System && BaseDir == DefaultBaseDirGet() { BaseDir = DefaultSystemBaseDirGet() } //FIXME Old migration code. Remove someday. oldname := strings.Replace(BaseDir, "pacifica", "myemsl", -1) oldname = strings.Replace(oldname, "Pacifica", "MyEMSL", -1) fi, err := os.Stat(oldname) if err == nil && fi.IsDir() { fi, err := os.Stat(oldname) if err != nil { log.Printf("This system needs to be migrated but cant. Error %v.\n", err) os.Exit(-1) } if !fi.IsDir() { log.Printf("This system needs to be migrated but cant. Error %v.\n", err) os.Exit(-1) } file, err := os.Open(oldname) if err != nil { log.Printf("This system needs to be migrated but cant. Error %v.\n", err) os.Exit(-1) } os.MkdirAll(BaseDir, 0755) names, err := file.Readdirnames(-1) if err != nil { log.Printf("This system needs to be migrated but cant. Error %v.\n", err) os.Exit(-1) } for _, n := range names { err = os.Rename(filepath.Join(oldname, n), filepath.Join(BaseDir, n)) if err != nil { log.Printf("This system needs to be migrated but cant. Error %v.\n", err) os.Exit(-1) } } err = os.Remove(oldname) if err != nil { log.Printf("This system needs to be migrated but cant. Error %v.\n", err) os.Exit(-1) } } //FIXME End of old migration code. os.MkdirAll(BaseDir, 0755) setupLogger(LogDirGet()) StateDir = filepath.Join(BaseDir, "state") os.MkdirAll(StateDir, 0700) os.MkdirAll(filepath.Join(BaseDir, "auth"), 0755) if System && platform.PlatformGet() == platform.Windows { err := Cacls(BaseDir, "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Users:r", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) os.Exit(-1) } } if System && platform.PlatformGet() == platform.Windows { err := Cacls(StateDir, "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) os.Exit(-1) } } _, err = os.Stat(BaseDir) if err != nil { log.Printf("The specified basedir is not valid, %v\n", err) } VersionCheckerInit() userdInit() uuidInit() log.Printf("Got uuid %s\n", Uuid) }
func passcredsHandle(cm *CredsManager, w http.ResponseWriter, req *http.Request) { if web.AuthCheck(w, req) { if req.Method != "PUT" { w.WriteHeader(http.StatusMethodNotAllowed) } else { file, err := ioutil.TempFile(filepath.Join(common.BaseDir, "auth", "tmpcreds"), "creds") if err != nil { //FIXME what to return here? w.WriteHeader(http.StatusBadRequest) return } var buffer [BUFFSIZE]byte total := 0 for { num, err := req.Body.Read(buffer[:]) if (err != nil && err != io.EOF) || num < 0 { w.WriteHeader(http.StatusBadRequest) log.Printf("Failed to read during pass creds. %v %v", file.Name(), err) file.Close() os.Remove(file.Name()) return } if num == 0 { break } total += num if total > MAXCRED { w.WriteHeader(http.StatusBadRequest) log.Printf("Cred call too big.") file.Close() os.Remove(file.Name()) return } _, err = file.Write(buffer[0:num]) if err != nil { //FIXME what to return here? w.WriteHeader(http.StatusBadRequest) log.Printf("Failed to write to temp cred file. %v\n", err) file.Close() os.Remove(file.Name()) return } } _, err = file.Seek(0, 0) if err != nil { //FIXME what to return here? w.WriteHeader(http.StatusBadRequest) os.Remove(file.Name()) return } auth := pacificaauth.NewAuth(file) file.Close() log.Println("testauth:", auth.Services["testauth"]) client := auth.NewClient() r, err := client.Get(auth.Services["testauth"]) if err != nil { log.Println(err) os.Remove(file.Name()) return } log.Println(r.StatusCode) user := web.AuthUser(req) upath := filepath.Join(common.BaseDir, "auth", "creds", common.FsEncodeUser(user)) if platform.PlatformGet() == platform.Windows { err = os.Remove(upath) } err = os.Rename(file.Name(), upath) if err != nil { log.Println(err) os.Remove(file.Name()) return } if cm.userCreds[user] != nil { oldclient := cm.userCreds[user].NewClient() r, err = oldclient.Get(auth.Services["logout"]) if err != nil { log.Println(err) } else { log.Printf("Logged out %v: %v\n", user, r.StatusCode) } } cm.userCreds[user] = auth cm.outage[user] = nil } } }
func bundlerNew(bm *BundleManager) *bundler { self := &bundler{bm: bm, wake: sync.NewCond(&sync.Mutex{})} err := bm.BundleStateChangeWatchSet(BundleState_ToBundle, func(user string, bundle_id int, state BundleState) { self.Wakeup() }) if err != nil { log.Printf("Failed to register wakeup callback with the bundle manager.") return nil } go func() { for { found := false ids, err := self.bm.bundleIdsForStateGet(BundleState_ToBundle) if err == nil && ids != nil { for user, list := range ids { for _, id := range list { log.Printf("Got bundles %v %v\n", user, id) bundle_filename := filepath.Join(common.BaseDir, "bundles", "inprogress", strconv.Itoa(id)+".tar") file, err := os.Create(bundle_filename) if err != nil { log.Printf("Could not open temp file. %v", err) continue } file.Close() if common.System { if platform.PlatformGet() == platform.Linux { cmd := exec.Command("setfacl", "-m", "user:"******":rw", bundle_filename) err = cmd.Run() if err != nil { log.Printf("Failed to set acl on bundle. %v\n", err) continue } } else if platform.PlatformGet() == platform.Windows { //TODO - remove or fix so that permissions are set for system user only. /*userstr := common.UserdDefaultUsername() + ":C" err = common.Cacls(bundle_filename, "/p", "NT AUTHORITY\\SYSTEM:f", userstr, "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) continue }*/ } } err = bundleFiles(bundle_filename, user, id) if err != nil { continue } var newstate BundleState metadata_filename := filepath.Join(common.BaseDir, "bundles", "inprogress", strconv.Itoa(id)+".txt") file, err = os.Create(metadata_filename) if err != nil { log.Printf("Could not open temp file. %v", err) continue } else { err = writeMetadata(self.bm, user, id, file) file.Close() if err != nil { continue } _, _, fe, _, err := common.UserBundleFile(user, bundle_filename, metadata_filename, "metadata.txt") if err != nil || rpc.BundleFileErrorIsError(fe) { log.Printf("Failed to add metadata to bundle. %v", err) continue } newstate = BundleState_ToUpload } if common.System { if platform.PlatformGet() == platform.Linux { cmd := exec.Command("setfacl", "-x", "user:"******"Failed to remove acl on bundle. %v\n", err) continue } } else if platform.PlatformGet() == platform.Windows { err = common.Cacls(bundle_filename, "/p", "NT AUTHORITY\\SYSTEM:f", "BUILTIN\\Administrators:F") if err != nil { log.Printf("Failed to run cacls %v\n", err) continue } } } bundle_new_filename := filepath.Join(common.BaseDir, "bundles", strconv.Itoa(id)+".tar") os.Remove(bundle_new_filename) err = os.Rename(bundle_filename, bundle_new_filename) if err != nil { log.Printf("Failed to rename bundle. %v\n", err) continue } err = bm.bundleStringSet(user, id, "bundle_location", bundle_new_filename) if err != nil { log.Printf("Failed to set bundle location. %v\n", err) continue } err = bm.BundleStateSet(user, id, newstate) if err != nil { log.Printf("Failed to transition bundle from bundling to upload. %v\n", err) continue } found = true } } } if found == false { self.wake.L.Lock() count, err := self.bm.bundleIdsForStateCount(BundleState_ToBundle) if err == nil && count < 1 { self.wake.Wait() } self.wake.L.Unlock() } } }() return self }