Example #1
0
// 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
}
Example #2
0
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)
}
Example #3
0
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)
}
Example #4
0
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)
}
Example #5
0
// 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
}
Example #6
0
// 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"))
}