diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2011-10-08 20:30:28 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2011-10-08 20:30:28 +0200 |
| commit | 5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch) | |
| tree | 1a81af141708b826e9c61e8a04019994fcca8298 /src/sh/user.cc | |
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/sh/user.cc')
| -rw-r--r-- | src/sh/user.cc | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/src/sh/user.cc b/src/sh/user.cc new file mode 100644 index 0000000..94285ef --- /dev/null +++ b/src/sh/user.cc | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | |||
| 22 | int allow(const sref& s,const sref& grp,time_t now,int rootok) | ||
| 23 | { | ||
| 24 | if(grp.empty()) return 1; | ||
| 25 | int n=s.find(':'); | ||
| 26 | sref a=s.left(n); | ||
| 27 | if(rootok>=0&&a==root_tag) return rootok; | ||
| 28 | else if(grp==root_tag||a!=grp) return 0; | ||
| 29 | n=(a=s.past(n,1)).find(':'); sref b=a.past(n,1); a=a.left(n); | ||
| 30 | return (a.empty()||atoi(a)<=now)&&(b.empty()||now<atoi(b)); | ||
| 31 | } | ||
| 32 | |||
| 33 | //////////////////////////////////////////////////////////////////////// | ||
| 34 | |||
| 35 | user_t::user_t(const user_t& us) : list(user_tabs) | ||
| 36 | { | ||
| 37 | for(int i=0;i<user_tabs;i++) list[i]=us.list[i]; | ||
| 38 | } | ||
| 39 | |||
| 40 | void user_t::operator=(const user_t& us) | ||
| 41 | { | ||
| 42 | list.resize(user_tabs); | ||
| 43 | for(int i=0;i<user_tabs;i++) list[i]=us.list[i]; | ||
| 44 | } | ||
| 45 | |||
| 46 | void user_t::reset() | ||
| 47 | { | ||
| 48 | list.resize(user_tabs); | ||
| 49 | uid()=itoa(0); | ||
| 50 | group()=itoa(0); | ||
| 51 | fail()=itoa(0); | ||
| 52 | pin().clear(); | ||
| 53 | alias().clear(); | ||
| 54 | email().clear(); | ||
| 55 | name().clear(); | ||
| 56 | last()=itoa(0); | ||
| 57 | lastin()=lastin_def; | ||
| 58 | access().clear(); | ||
| 59 | } | ||
| 60 | |||
| 61 | int user_t::allow(const sref& grp,time_t now,int rootok) | ||
| 62 | { | ||
| 63 | sref first,rest=access(); | ||
| 64 | while(Split(first,rest)) if(::allow(first,grp,now,rootok)) return 1; | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | int user_t::allow_list(const sref& grps,time_t now,int rootok) | ||
| 69 | { | ||
| 70 | sref first,rest=grps; | ||
| 71 | while(Split(first,rest)) if(!allow(first,now,rootok)) return 0; | ||
| 72 | return 1; | ||
| 73 | } | ||
| 74 | |||
| 75 | void user_t::add(const sref& grp) | ||
| 76 | { | ||
| 77 | sref first,rest=access(); | ||
| 78 | while(Split(first,rest)) if(first.left_first(':')==grp.left_first(':')) return; | ||
| 79 | mstring clear=grp; | ||
| 80 | if(clear.find(':')<0) { clear+=':'; clear+=itoa(time(0)); } | ||
| 81 | if(access().nempty()) access()+=' '; access()+=clear; | ||
| 82 | } | ||
| 83 | |||
| 84 | void user_t::add_list(const sref& grps) { | ||
| 85 | sref first,rest=grps; | ||
| 86 | while(Split(first,rest)) add(first); | ||
| 87 | } | ||
| 88 | |||
| 89 | void user_t::rem(const sref& grp) | ||
| 90 | { | ||
| 91 | mstring m; | ||
| 92 | sref first,rest=access(); | ||
| 93 | while(Split(first,rest)) | ||
| 94 | if(first.left_first(':')!=grp) { if(m.nempty()) m+=' '; m+=first; } | ||
| 95 | access()=m; | ||
| 96 | } | ||
| 97 | |||
| 98 | void user_t::rem_list(const sref& grps) | ||
| 99 | { | ||
| 100 | sref first,rest=grps; | ||
| 101 | while(Split(first,rest)) rem(first); | ||
| 102 | } | ||
| 103 | |||
| 104 | //////////////////////////////////////////////////////////////////////// | ||
| 105 | |||
| 106 | static dbmap* GetDB(Env& env,const sref& name) | ||
| 107 | { | ||
| 108 | dbref_t* p=(dbref_t*)env.toks->get(name); | ||
| 109 | if(!env.is_clear(p)||!p->is_dbref()) THROW("htc: could not find system db "<<name); | ||
| 110 | p->db.remap(); | ||
| 111 | return &p->db; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int FindUser(Env& env,const sref& name) | ||
| 115 | { | ||
| 116 | dbmap* users=GetDB(env,USERS_tag); | ||
| 117 | for(int i=0;i<users->size();i++) { | ||
| 118 | if(users->at(i,user_alias)==name) return atoi(users->at(i,user_uid)); | ||
| 119 | sref first,rest=users->at(i,user_email); | ||
| 120 | while(Split(first,rest)) if(eqn(first,name)) return atoi(users->at(i,user_uid)); | ||
| 121 | } | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | //////////////////////////////////////////////////////////////////////// | ||
| 126 | |||
| 127 | TOK_IMPL(setgroup) { Req(env)->group=First(env[0]); } | ||
| 128 | TOK_IMPL(group) { out<<Req(env)->group; } | ||
| 129 | |||
| 130 | TOK_IMPL(getgroups) { | ||
| 131 | dbmap* users=GetDB(env,USERS_tag); | ||
| 132 | mset m; | ||
| 133 | for(int i=0;i<users->size();i++) { | ||
| 134 | sref first,rest=users->at(i,user_access); | ||
| 135 | while(Split(first,rest)) m.insert(first.left_first(':')); | ||
| 136 | } | ||
| 137 | out<<m; | ||
| 138 | } | ||
| 139 | |||
| 140 | //////////////////////////////////////////////////////////////////////// | ||
| 141 | |||
| 142 | TOK_IMPL(getuser) { | ||
| 143 | out<<FindUser(env,env[0]); | ||
| 144 | } | ||
| 145 | |||
| 146 | TOK_IMPL(setuser) { | ||
| 147 | dbmap* users=GetDB(env,USERS_tag); | ||
| 148 | int row=users->Find(env[0]); | ||
| 149 | if(row>=0) users->Get(row,Req(env)->user.list); | ||
| 150 | else Req(env)->user.reset(); | ||
| 151 | } | ||
| 152 | |||
| 153 | TOK_IMPL(remuser) { | ||
| 154 | dbmap* users=GetDB(env,USERS_tag); | ||
| 155 | int row=users->Find(env[0]); | ||
| 156 | if(row>=0) users->Rem(row); | ||
| 157 | } | ||
| 158 | |||
| 159 | TOK_IMPL(newuser) { | ||
| 160 | static const charset namends("*@.+"); | ||
| 161 | user_t user; | ||
| 162 | sref first,rest=env[0]; | ||
| 163 | Split(first,rest); | ||
| 164 | user.group()=first.left_first(':'); | ||
| 165 | do user.add(first); | ||
| 166 | while(Split(first,rest)); | ||
| 167 | user.pin()=Random(4); | ||
| 168 | user.email()=env[1]; | ||
| 169 | rest=env[1]; while(Split(first,rest)) if(FindUser(env,first)) { out<<0; return; } | ||
| 170 | mstring tag,alias=env[1].left_first_of(namends); | ||
| 171 | while(FindUser(env,alias+tag)) tag=itoa(atoi(tag)+1); | ||
| 172 | user.alias()=alias+tag; | ||
| 173 | user.name()=env[2]; | ||
| 174 | dbmap* users=GetDB(env,USERS_tag); | ||
| 175 | if(users->empty()) user.uid()=itoa(1); | ||
| 176 | else user.uid()=itoa(atoi(users->at(users->size()-1,user_uid))+1); | ||
| 177 | int row=users->Insert(user.list,1); | ||
| 178 | if(row<0) THROW("htc: could not add user - record not unique"); | ||
| 179 | out<<user.uid(); | ||
| 180 | } | ||
| 181 | |||
| 182 | ////////////////////////////////////////////////////////////////////////// | ||
| 183 | |||
| 184 | TOK_IMPL(user_id) { out<<Req(env)->user.uid(); } | ||
| 185 | TOK_IMPL(user_group) { out<<Req(env)->user.group(); } | ||
| 186 | TOK_IMPL(user_access) { out<<Req(env)->user.access(); } | ||
| 187 | TOK_IMPL(user_clear) { | ||
| 188 | sref first,rest=Req(env)->user.access(); int n=0; | ||
| 189 | while(Split(first,rest)) { if(n++) out.put(' '); out<<first.left_first(':'); } | ||
| 190 | } | ||
| 191 | |||
| 192 | TOK_IMPL(user_fail) { out<<Req(env)->user.fail(); } | ||
| 193 | TOK_IMPL(user_pin) { out<<Req(env)->user.pin(); } | ||
| 194 | TOK_IMPL(user_alias) { out<<Req(env)->user.alias(); } | ||
| 195 | TOK_IMPL(user_email) { out<<First(Req(env)->user.email()); } | ||
| 196 | TOK_IMPL(user_emails) { out<<Req(env)->user.email(); } | ||
| 197 | TOK_IMPL(user_name) { out<<Req(env)->user.name(); } | ||
| 198 | TOK_IMPL(user_last) { out<<Req(env)->user.last(); } | ||
| 199 | TOK_IMPL(user_lastin) { out<<Req(env)->user.lastin(); } | ||
| 200 | |||
| 201 | ////////////////////////////////////////////////////////////////////////// | ||
| 202 | |||
| 203 | TOK_IMPL(user_group_set) { Req(env)->user.group()=env[0]; } | ||
| 204 | TOK_IMPL(user_access_add) { Req(env)->user.add_list(env[0]); } | ||
| 205 | TOK_IMPL(user_access_rem) { Req(env)->user.rem_list(env[0]); } | ||
| 206 | TOK_IMPL(user_fail_set) { Req(env)->user.fail()=env[0]; } | ||
| 207 | TOK_IMPL(user_pin_set) { Req(env)->user.pin()=env[0]; } | ||
| 208 | TOK_IMPL(user_alias_set) { Req(env)->user.alias()=env[0]; } | ||
| 209 | TOK_IMPL(user_emails_set) { Req(env)->user.email()=env[0]; } | ||
| 210 | TOK_IMPL(user_name_set) { Req(env)->user.name()=env[0]; } | ||
| 211 | TOK_IMPL(user_last_set) { Req(env)->user.last()=env[0]; } | ||
| 212 | TOK_IMPL(user_lastin_set) { Req(env)->user.lastin()=env[0]; } | ||
| 213 | |||
| 214 | ////////////////////////////////////////////////////////// | ||
| 215 | |||
| 216 | TOK_IMPL(user_update) { | ||
| 217 | htc_req* htc=Req(env); | ||
| 218 | int uid=atoi(htc->user.uid()); | ||
| 219 | int who=FindUser(env,htc->user.alias()); | ||
| 220 | if(who&&who!=uid) return; | ||
| 221 | sref first,rest=htc->user.email(); | ||
| 222 | while(Split(first,rest)) { | ||
| 223 | who=FindUser(env,first); | ||
| 224 | if(who&&who!=uid) return; | ||
| 225 | } | ||
| 226 | dbmap* users=GetDB(env,USERS_tag); | ||
| 227 | int row=users->Find(htc->user.uid()); | ||
| 228 | if(row>=0) users->Set(row,htc->user.list); | ||
| 229 | } | ||
| 230 | |||
| 231 | ////////////////////////////////////////////////////////// | ||
| 232 | |||
| 233 | TOK_IMPL(su) { | ||
| 234 | htc_req* htc=Req(env); | ||
| 235 | user_t tmp(htc->user); | ||
| 236 | dbmap* users=GetDB(env,USERS_tag); | ||
| 237 | int row=users->Find(env[0]); | ||
| 238 | if(row>=0) { | ||
| 239 | try { | ||
| 240 | users->Get(row,htc->user.list); | ||
| 241 | env.parg(out,1); | ||
| 242 | htc->user=tmp; | ||
| 243 | } | ||
| 244 | catch(...) { | ||
| 245 | htc->user=tmp; | ||
| 246 | throw; | ||
| 247 | } | ||
| 248 | } | ||
| 249 | else env.parg(out,2); | ||
| 250 | } | ||
| 251 | |||
| 252 | ////////////////////////////////////////////////////////// | ||
| 253 | |||
| 254 | void envAddUser(tokmap& T) throw(merror_t) | ||
| 255 | { | ||
| 256 | TOK_ADD(setgroup,"x",tok_t::SYSONLY, | ||
| 257 | "%Set current group\n" | ||
| 258 | "%Syntax: \\setgroup{group}\n" | ||
| 259 | "%\n" | ||
| 260 | "%Nop function; only for logging and structure.\n" | ||
| 261 | ); | ||
| 262 | TOK_ADD(group,"",tok_t::PUBLIC, | ||
| 263 | "%Get current group\n" | ||
| 264 | "%Syntax: \\group\n" | ||
| 265 | "%\n" | ||
| 266 | "%Nop function; only for logging and structure.\n" | ||
| 267 | ); | ||
| 268 | |||
| 269 | TOK_ADD(getgroups,"",tok_t::PUBLIC, | ||
| 270 | "%Get all groups\n" | ||
| 271 | "%Syntax: \\getgroups\n" | ||
| 272 | "%\n" | ||
| 273 | "%Scans users db for all groups used\n" | ||
| 274 | ); | ||
| 275 | |||
| 276 | /////////////////////////////////////////////////// | ||
| 277 | |||
| 278 | TOK_ADD(getuser,"x",tok_t::SYSONLY, | ||
| 279 | "%Get user ID\n" | ||
| 280 | "%Syntax: \\getuser{alias/email}\n" | ||
| 281 | "%\n" | ||
| 282 | "%Returns the uid if found, or zero if not found\n" | ||
| 283 | ); | ||
| 284 | TOK_ADD(setuser,"x",tok_t::SYSONLY, | ||
| 285 | "%Set current user\n" | ||
| 286 | "%Syntax: \\setuser{uid}\n" | ||
| 287 | ); | ||
| 288 | TOK_ADD(remuser,"x",tok_t::SYSONLY, | ||
| 289 | "%Remove user\n" | ||
| 290 | "%Syntax: \\remuser{uid}\n" | ||
| 291 | ); | ||
| 292 | TOK_ADD(newuser,"xxx",tok_t::SYSONLY, | ||
| 293 | "%Add a new user\n" | ||
| 294 | "%Syntax: \\newuser{clear}{email}{name}\n" | ||
| 295 | "%\n" | ||
| 296 | "%Returns the new uid if successful, otherwise zero.\n" | ||
| 297 | ); | ||
| 298 | |||
| 299 | /////////////////////////////////////////////////// | ||
| 300 | |||
| 301 | TOK_ADD(user_id,"",tok_t::PUBLIC, | ||
| 302 | "%Get uid of current user\n" | ||
| 303 | "%Syntax: \\user.id\n" | ||
| 304 | ); | ||
| 305 | TOK_ADD(user_group,"",tok_t::PUBLIC, | ||
| 306 | "%Get group of current user\n" | ||
| 307 | "%Syntax: \\user.group\n" | ||
| 308 | ); | ||
| 309 | TOK_ADD(user_access,"",tok_t::PUBLIC, | ||
| 310 | "%Get access of current user\n" | ||
| 311 | "%Syntax: \\user.access\n" | ||
| 312 | ); | ||
| 313 | TOK_ADD(user_clear,"",tok_t::PUBLIC, | ||
| 314 | "%Get clearance of current user\n" | ||
| 315 | "%Syntax: \\user.clear\n" | ||
| 316 | "%\n" | ||
| 317 | "%This is a compiled list, without the time info.\n" | ||
| 318 | ); | ||
| 319 | TOK_ADD(user_fail,"",tok_t::PUBLIC, | ||
| 320 | "%Get fail number of current user\n" | ||
| 321 | "%Syntax: \\user.fail\n" | ||
| 322 | ); | ||
| 323 | TOK_ADD(user_pin,"",tok_t::SYSONLY, | ||
| 324 | "%Get pin of current user\n" | ||
| 325 | "%Syntax: \\user.pin\n" | ||
| 326 | ); | ||
| 327 | TOK_ADD(user_alias,"",tok_t::PUBLIC, | ||
| 328 | "%Get alias of current user\n" | ||
| 329 | "%Syntax: \\user.alias\n" | ||
| 330 | ); | ||
| 331 | TOK_ADD(user_email,"",tok_t::PUBLIC, | ||
| 332 | "%Get email of current user\n" | ||
| 333 | "%Syntax: \\user.email\n" | ||
| 334 | "%\n" | ||
| 335 | "%Note that the email list may contain several addresses;\n" | ||
| 336 | "%this function returns the first in the list.\n" | ||
| 337 | ); | ||
| 338 | TOK_ADD(user_emails,"",tok_t::PUBLIC, | ||
| 339 | "%Get all email addresses of current user\n" | ||
| 340 | "%Syntax: \\user.emails\n" | ||
| 341 | ); | ||
| 342 | TOK_ADD(user_name,"",tok_t::PUBLIC, | ||
| 343 | "%Get name of current user\n" | ||
| 344 | "%Syntax: \\user.name\n" | ||
| 345 | ); | ||
| 346 | TOK_ADD(user_last,"",tok_t::PUBLIC, | ||
| 347 | "%Get last time logged in of current user\n" | ||
| 348 | "%Syntax: \\user.last\n" | ||
| 349 | ); | ||
| 350 | TOK_ADD(user_lastin,"",tok_t::PUBLIC, | ||
| 351 | "%Get last IP address of current user\n" | ||
| 352 | "%Syntax: \\user.lastin\n" | ||
| 353 | ); | ||
| 354 | |||
| 355 | /////////////////////////////////////////////////// | ||
| 356 | |||
| 357 | TOK_ADD(user_group_set,"x",tok_t::SYSONLY, | ||
| 358 | "%Set group of current user\n" | ||
| 359 | "%Syntax: \\user.group.set{group}\n" | ||
| 360 | "%\n" | ||
| 361 | "%Note that the changes take effect after a \\user.update\n" | ||
| 362 | ); | ||
| 363 | TOK_ADD(user_access_add,"x",tok_t::SYSONLY, | ||
| 364 | "%Add access to current user\n" | ||
| 365 | "%Syntax: \\user.access.add{group:start:stop}\n" | ||
| 366 | "%\n" | ||
| 367 | "%The :start:stop part may be omitted, in which case\n" | ||
| 368 | "%a start value of now, and a stop value of nil is set.\n" | ||
| 369 | "%\n" | ||
| 370 | "%In case of several group strings, they are all added.\n" | ||
| 371 | "%\n" | ||
| 372 | "%Note that the changes take effect after a \\user.update\n" | ||
| 373 | ); | ||
| 374 | TOK_ADD(user_access_rem,"x",tok_t::SYSONLY, | ||
| 375 | "%Remove access from current user\n" | ||
| 376 | "%Syntax: \\user.access.rem{group}\n" | ||
| 377 | "%\n" | ||
| 378 | "%In case of several groups, they are all removed.\n" | ||
| 379 | "%\n" | ||
| 380 | "%Note that the changes take effect after a \\user.update\n" | ||
| 381 | ); | ||
| 382 | TOK_ADD(user_fail_set,"x",tok_t::SYSONLY, | ||
| 383 | "%Set fail number of current user\n" | ||
| 384 | "%Syntax: \\user.fail.set{fail}\n" | ||
| 385 | "%\n" | ||
| 386 | "%Note that the changes take effect after a \\user.update\n" | ||
| 387 | ); | ||
| 388 | TOK_ADD(user_pin_set,"x",tok_t::SYSONLY, | ||
| 389 | "%Set pin of current user\n" | ||
| 390 | "%Syntax: \\user.pin.set{pin}\n" | ||
| 391 | "%\n" | ||
| 392 | "%Note that the changes take effect after a \\user.update\n" | ||
| 393 | ); | ||
| 394 | TOK_ADD(user_alias_set,"x",tok_t::SYSONLY, | ||
| 395 | "%Set alias of current user\n" | ||
| 396 | "%Syntax: \\user.alias.set{alias}\n" | ||
| 397 | "%\n" | ||
| 398 | "%Note that the changes take effect after a \\user.update\n" | ||
| 399 | ); | ||
| 400 | TOK_ADD(user_emails_set,"x",tok_t::SYSONLY, | ||
| 401 | "%Set all email addresses of current user\n" | ||
| 402 | "%Syntax: \\user.emails.set{emails}\n" | ||
| 403 | "%\n" | ||
| 404 | "%Note that the changes take effect after a \\user.update\n" | ||
| 405 | ); | ||
| 406 | TOK_ADD(user_name_set,"x",tok_t::SYSONLY, | ||
| 407 | "%Set name of current user\n" | ||
| 408 | "%Syntax: \\user.name.set{name}\n" | ||
| 409 | "%\n" | ||
| 410 | "%Note that the changes take effect after a \\user.update\n" | ||
| 411 | ); | ||
| 412 | TOK_ADD(user_last_set,"x",tok_t::SYSONLY, | ||
| 413 | "%Set last time logged in of current user\n" | ||
| 414 | "%Syntax: \\user.last.set{last}\n" | ||
| 415 | "%\n" | ||
| 416 | "%Note that the changes take effect after a \\user.update\n" | ||
| 417 | ); | ||
| 418 | TOK_ADD(user_lastin_set,"x",tok_t::SYSONLY, | ||
| 419 | "%Set last IP address of current user\n" | ||
| 420 | "%Syntax: \\user.lastin.set{addr}\n" | ||
| 421 | "%\n" | ||
| 422 | "%Note that the changes take effect after a \\user.update\n" | ||
| 423 | ); | ||
| 424 | |||
| 425 | /////////////////////////////////////////////////// | ||
| 426 | |||
| 427 | TOK_ADD(user_update,"",tok_t::SYSONLY, | ||
| 428 | "%Update the current user\n" | ||
| 429 | "%Syntax: \\user.update\n" | ||
| 430 | "%\n" | ||
| 431 | "%All changes a synchronous and immediately available.\n" | ||
| 432 | ); | ||
| 433 | |||
| 434 | /////////////////////////////////////////////////// | ||
| 435 | |||
| 436 | TOK_ADD(su,"xr?",tok_t::SYSONLY, | ||
| 437 | "%Set user temporary\n" | ||
| 438 | "%Syntax: \\su{uid}{body}<else>\n" | ||
| 439 | "%\n" | ||
| 440 | "%If set successfully, evaluates body, otherwise <else>.\n" | ||
| 441 | ); | ||
| 442 | |||
| 443 | /////////////////////////////////////////////////// | ||
| 444 | |||
| 445 | } | ||
