Add client interface for GRANT.
TODO: implement notifications of grant privilege changes to the target.
This commit is contained in:
parent
5b2fb1a7eb
commit
e794d39a80
2 changed files with 118 additions and 32 deletions
|
@ -30,59 +30,40 @@ static struct flag_list flaglist[] = {
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int m_grant(struct Client *, struct Client *, int, const char **);
|
||||||
static int me_grant(struct Client *, struct Client *, int, const char **);
|
static int me_grant(struct Client *, struct Client *, int, const char **);
|
||||||
|
|
||||||
struct Message grant_msgtab = {
|
struct Message grant_msgtab = {
|
||||||
"GRANT", 0, 0, 0, MFLG_SLOW,
|
"GRANT", 0, 0, 0, MFLG_SLOW,
|
||||||
{mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_grant, 4}, mg_ignore}
|
{mg_unreg, {m_grant, 4}, mg_ignore, mg_ignore, {me_grant, 4}, mg_ignore}
|
||||||
};
|
};
|
||||||
|
|
||||||
mapi_clist_av1 grant_clist[] = { &grant_msgtab, NULL };
|
mapi_clist_av1 grant_clist[] = { &grant_msgtab, NULL };
|
||||||
DECLARE_MODULE_AV1(grant, NULL, NULL, grant_clist, NULL, NULL, "Charybdis development team");
|
DECLARE_MODULE_AV1(grant, NULL, NULL, grant_clist, NULL, NULL, "Charybdis development team");
|
||||||
|
|
||||||
/*
|
static void
|
||||||
* me_grant
|
apply_flags(struct membership *msptr, const char *flagspec, unsigned int flagmask)
|
||||||
*
|
|
||||||
* parv[1] = channel
|
|
||||||
* parv[2] = target UID
|
|
||||||
* parv[3] = flag spec
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
me_grant(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
|
||||||
{
|
{
|
||||||
struct Channel *chptr;
|
|
||||||
struct Client *target_p;
|
|
||||||
struct membership *msptr;
|
|
||||||
char *s, *t, *p;
|
char *s, *t, *p;
|
||||||
|
|
||||||
if (!(chptr = find_channel(parv[1])))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(target_p = find_person(parv[2])))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Makes no sense to do this for non-local users */
|
|
||||||
if(!MyClient(target_p))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(msptr = find_channel_membership(chptr, target_p)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* unset all chanroles as we're setting new ones */
|
/* unset all chanroles as we're setting new ones */
|
||||||
msptr->roles = 0;
|
msptr->roles = 0;
|
||||||
|
|
||||||
t = LOCAL_COPY(parv[3]);
|
t = LOCAL_COPY(flagspec);
|
||||||
for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p))
|
for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p))
|
||||||
{
|
{
|
||||||
const char *priv = s + 1; /* The actual priv */
|
const char *priv = s + 1; /* The actual priv */
|
||||||
struct flag_list *fl;
|
struct flag_list *fl;
|
||||||
int flag = 0;
|
unsigned int flag = 0;
|
||||||
|
|
||||||
/* Go through the flags list... */
|
/* Go through the flags list... */
|
||||||
for(fl = flaglist; fl->name != NULL; fl++)
|
for(fl = flaglist; fl->name != NULL; fl++)
|
||||||
{
|
{
|
||||||
if (strcasecmp(fl->name, priv) == 0)
|
if (strcasecmp(fl->name, priv) == 0)
|
||||||
{
|
{
|
||||||
|
/* flagmask exists to ensure users can't give privileges they
|
||||||
|
* don't possess themselves */
|
||||||
|
if (!flagmask || (flagmask & fl->flag))
|
||||||
flag = fl->flag;
|
flag = fl->flag;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +78,111 @@ me_grant(struct Client *client_p, struct Client *source_p, int parc, const char
|
||||||
else if (s[0] == '+')
|
else if (s[0] == '+')
|
||||||
SetChanRole(msptr, flag);
|
SetChanRole(msptr, flag);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* m_grant
|
||||||
|
*
|
||||||
|
* parv[1] = channel
|
||||||
|
* parv[2] = target nickname
|
||||||
|
* parv[3] = flag spec
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
m_grant(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||||
|
{
|
||||||
|
struct Channel *chptr;
|
||||||
|
struct Client *target_p;
|
||||||
|
struct membership *cmsptr, *tmsptr;
|
||||||
|
char flagspec[BUFSIZE];
|
||||||
|
const char *flagptr;
|
||||||
|
|
||||||
|
if(parc > 4)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *buf = flagspec;
|
||||||
|
|
||||||
|
flagptr = flagspec;
|
||||||
|
|
||||||
|
for (i = 3; i < parc; i++)
|
||||||
|
/* Rest assured it can't overflow, parv contents will always be < BUFSIZE
|
||||||
|
* --Elizabeth */
|
||||||
|
buf += rb_sprintf(buf, "%s ", parv[i]);
|
||||||
|
|
||||||
|
*buf = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
flagptr = parv[3];
|
||||||
|
|
||||||
|
if (!(chptr = find_channel(parv[1])))
|
||||||
|
{
|
||||||
|
sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(cmsptr = find_channel_membership(chptr, client_p)))
|
||||||
|
/* Can't happen */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check for grant privilege */
|
||||||
|
if(get_channel_access(source_p, cmsptr, CHANROLE_GRANT) < CHFL_CHANOP)
|
||||||
|
{
|
||||||
|
sendto_one_numeric(source_p, ERR_CHANOPRIVSNEEDED, form_str(ERR_CHANOPRIVSNEEDED),
|
||||||
|
me.name, source_p->name, parv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(target_p = find_named_person(parv[2])))
|
||||||
|
{
|
||||||
|
sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send it to the server the user is on if not local */
|
||||||
|
if(!MyClient(target_p))
|
||||||
|
{
|
||||||
|
struct Client *cptr = target_p->servptr;
|
||||||
|
sendto_one(cptr, ":%s ENCAP %s GRANT %s %s :%s",
|
||||||
|
get_id(source_p, cptr), cptr->name, chptr->chname,
|
||||||
|
get_id(target_p, cptr), flagptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(tmsptr = find_channel_membership(chptr, target_p)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
apply_flags(tmsptr, flagptr, cmsptr->roles);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* me_grant
|
||||||
|
*
|
||||||
|
* parv[1] = channel
|
||||||
|
* parv[2] = target UID
|
||||||
|
* parv[3] = flag spec
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
me_grant(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||||
|
{
|
||||||
|
struct Channel *chptr;
|
||||||
|
struct Client *target_p;
|
||||||
|
struct membership *msptr;
|
||||||
|
|
||||||
|
if (!(chptr = find_channel(parv[1])))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(target_p = find_person(parv[2])))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Makes no sense to do this for non-local users */
|
||||||
|
if(!MyClient(target_p))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(msptr = find_channel_membership(chptr, target_p)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
apply_flags(msptr, parv[3], 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -903,7 +903,7 @@ chm_op(struct Client *source_p, struct Channel *chptr,
|
||||||
mode_changes[mode_count++].client = targ_p;
|
mode_changes[mode_count++].client = targ_p;
|
||||||
|
|
||||||
mstptr->flags |= CHFL_CHANOP;
|
mstptr->flags |= CHFL_CHANOP;
|
||||||
if (msptr->roles & CHANROLE_UNSET)
|
if (mstptr->roles & CHANROLE_UNSET)
|
||||||
{
|
{
|
||||||
mstptr->roles &= ~CHANROLE_UNSET;
|
mstptr->roles &= ~CHANROLE_UNSET;
|
||||||
mstptr->roles = CHANROLE_INITIAL | CHANROLE_INHERIT;
|
mstptr->roles = CHANROLE_INITIAL | CHANROLE_INHERIT;
|
||||||
|
|
Loading…
Reference in a new issue