// HasOperCommand returns whether the user has access to the given oper command. // This checks for the presence of the command in their opcommand list, and // if a flag is given, also checks for the presence of that, including the // "on" keyword for default privileges. // // Unlike HasOpFlag, this SHOULD be used directly to determine if a user can // run the given command, as we extend the ability to adjust who has access to // commands to the server administration via configuration instead of modules // in the case of oper commands. func HasOperCommand(u *core.User, flag, command string) bool { var words []string // Check commands. words = strings.Fields(u.Data("opcommands")) for _, word := range words { if word == command { return true } } // Check flags. words = strings.Fields(u.Data("op")) for _, word := range words { if word == flag { return true } if word == "on" { for _, defword := range defServerOp { if defword == flag { return true } } } } return false }
func cmdOperflags(source interface{}, params [][]byte) { c := source.(*Client) var target *core.User if target = core.GetUserByNick(string(params[0])); target == nil { c.SendLineTo(nil, "401", "%s %s :No such user.", c.u.Nick(), params[0]) return } var flags string if flags = target.Data("op"); flags == "" { c.SendLineTo(nil, "304", ":OPERFLAGS: %s has no server oper flags.", target.Nick()) return } if flags == "on" { flags = perm.DefaultServerOp() } c.SendLineTo(nil, "304", ":OPERFLAGS: %s has server oper flags: %s", target.Nick(), flags) var commands string if commands = target.Data("opcommands"); commands == "" { return } c.SendLineTo(nil, "304", ":OPERFLAGS: %s also has the following specific commands: %s", target.Nick(), commands) }
func cmdUserhost(source interface{}, params [][]byte) { c := source.(*Client) nicks := strings.Fields(string(params[0])) var replyline string for _, nick := range nicks { var user *core.User if user = core.GetUserByNick(nick); user == nil { continue } if replyline != "" { replyline += " " } replyline += nick if user.Data("op") != "" { replyline += "*" } replyline += "=" if user.Data("away") != "" { replyline += "-" } else { replyline += "+" } replyline += user.GetHostname() } c.SendLineTo(nil, "302", ":%s", replyline) }
func cmdOpflags(source interface{}, params [][]byte) { c := source.(*Client) channame := string(params[0]) if channame[0] == '#' { channame = channame[1:] } var ch *core.Channel if ch = core.FindChannel("", channame); ch == nil { c.SendLineTo(nil, "403", "#%s :No such channel.", channame) return } // If the user isn't on the channel, don't let them check unless they // can view private channel data. if m := ch.GetMember(c.u); m == nil { if ok, err := perm.CheckChanViewData(me, c.u, ch, "members"); !ok { c.SendLineTo(nil, "482", "#%s :%s", ch.Name(), err) return } } var target *core.User if target = core.GetUserByNick(string(params[1])); target == nil { c.SendLineTo(nil, "401", "%s :No such user.", params[1]) return } var m *core.Membership if m = ch.GetMember(target); m == nil { c.SendLineTo(nil, "304", ":OPFLAGS #%s: %s is not in the channel.", ch.Name(), target.Nick()) return } if ok, err := perm.CheckMemberViewData(me, c.u, m, "op"); !ok { c.SendLineTo(nil, "482", "#%s :%s: %s", ch.Name(), target.Nick(), err) return } var flags string if flags = m.Data("op"); flags == "" { c.SendLineTo(nil, "304", ":OPFLAGS #%s: %s has no channel op flags.", ch.Name(), target.Nick()) return } if flags == "on" { flags = perm.DefaultChanOp() } c.SendLineTo(nil, "304", ":OPFLAGS #%s: %s has channel op flags: %s", ch.Name(), target.Nick(), flags) }
// ParseModeLine parses a line of mode changes into core.DataChange structs. // Redundant changes are compressed down into one. // An error is returned if unknown modes are encountered, or modes are dropped // due to missing parameters. The remainder of the modes are still parsed. // e is the user or channel being changed. func (p *ModeParser) ParseModeLine(source *core.User, e core.Extensible, modeline []byte, params []string) ([]core.DataChange, os.Error) { var adding bool = true var unknown string var missing string var param int modes := string(modeline) changes := make(map[string]core.DataChange) for _, char := range modes { if char == '+' { adding = true continue } else if char == '-' { adding = false continue } if v, ok := p.simple[char]; ok { if v, ok := p.extended[char]; ok { newchanges := v(adding, e, "") for _, it := range newchanges { changes[it.Name] = it } continue } var change core.DataChange change.Name = v if adding { change.Data = "on" } changes[change.Name] = change continue } if v, ok := p.parametered[char]; ok { var change core.DataChange if adding { if param >= len(params) { missing += string(char) continue } if v, ok := p.extended[char]; ok { newch := v(adding, e, params[param]) param++ for _, it := range newch { changes[it.Name] = it } continue } change.Name = v change.Data = params[param] param++ } else { if v, ok := p.extended[char]; ok { newchanges := v(adding, e, "") for _, it := range newchanges { changes[it.Name] = it } continue } change.Name = v } changes[change.Name] = change continue } if v, ok := p.list[char]; ok { if param >= len(params) { missing += string(char) continue } var change core.DataChange cparam := params[param] param++ if v, ok := p.extended[char]; ok { newchanges := v(adding, e, cparam) for _, it := range newchanges { if it.Data != "" { it.Data += fmt.Sprintf(" setby-%s setat-%d", source.GetSetBy(), time.Seconds()) } changes[it.Name] = it } continue } if adding { change.Name = v + " " + cparam change.Data = fmt.Sprintf("on setby-%s setat-%d", source.GetSetBy(), time.Seconds()) } else { change.Name = v + " " + cparam } changes[change.Name] = change continue } if v, ok := p.membership[char]; ok { var ch *core.Channel var ok bool if ch, ok = e.(*core.Channel); !ok { continue } if param >= len(params) { missing += string(char) continue } par := params[param] param++ if v, ok := p.extended[char]; ok { newchanges := v(adding, e, par) for _, it := range newchanges { if it.Member != nil { changes["m"+it.Member.User().ID()+" "+it.Name] = it } else { changes[it.Name] = it } } continue } var u *core.User var m *core.Membership if u = core.GetUser(par); u == nil { if u = core.GetUserByNick(par); u == nil { continue } } if m = ch.GetMember(u); m == nil { continue } var change core.DataChange change.Name = v change.Member = m if adding { change.Data = "on" } changes["m"+change.Member.User().ID()+" "+change.Name] = change continue } unknown += string(char) } // Turn the modes into a slice. c := make([]core.DataChange, 0, len(changes)) for _, change := range changes { c = append(c, change) } // Get the error, if we had one. var errstring string if unknown != "" { errstring += "Unknown mode letters: " + unknown if missing != "" { errstring += " " } } if missing != "" { errstring += "Missing parameters for: " + missing } var err os.Error if errstring != "" { err = os.NewError(errstring) } return c, err }
// Introduce a user to a given local server. func send_uid(l *local, u *core.User) { irc.SendFrom(l, from(nil), "UID %s 1 %d +i %s %s %s %s :%s", u.Nick(), u.NickTS(), u.GetIdent(), u.GetHostname(), u.GetIP(), u.ID(), u.Data("realname")) }