summaryrefslogtreecommitdiff
path: root/src/sh/user.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /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.cc445
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
22int 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
35user_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
40void 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
46void 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
61int 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
68int 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
75void 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
84void user_t::add_list(const sref& grps) {
85 sref first,rest=grps;
86 while(Split(first,rest)) add(first);
87}
88
89void 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
98void user_t::rem_list(const sref& grps)
99{
100 sref first,rest=grps;
101 while(Split(first,rest)) rem(first);
102}
103
104////////////////////////////////////////////////////////////////////////
105
106static 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
114static 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
127TOK_IMPL(setgroup) { Req(env)->group=First(env[0]); }
128TOK_IMPL(group) { out<<Req(env)->group; }
129
130TOK_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
142TOK_IMPL(getuser) {
143 out<<FindUser(env,env[0]);
144}
145
146TOK_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
153TOK_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
159TOK_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
184TOK_IMPL(user_id) { out<<Req(env)->user.uid(); }
185TOK_IMPL(user_group) { out<<Req(env)->user.group(); }
186TOK_IMPL(user_access) { out<<Req(env)->user.access(); }
187TOK_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
192TOK_IMPL(user_fail) { out<<Req(env)->user.fail(); }
193TOK_IMPL(user_pin) { out<<Req(env)->user.pin(); }
194TOK_IMPL(user_alias) { out<<Req(env)->user.alias(); }
195TOK_IMPL(user_email) { out<<First(Req(env)->user.email()); }
196TOK_IMPL(user_emails) { out<<Req(env)->user.email(); }
197TOK_IMPL(user_name) { out<<Req(env)->user.name(); }
198TOK_IMPL(user_last) { out<<Req(env)->user.last(); }
199TOK_IMPL(user_lastin) { out<<Req(env)->user.lastin(); }
200
201//////////////////////////////////////////////////////////////////////////
202
203TOK_IMPL(user_group_set) { Req(env)->user.group()=env[0]; }
204TOK_IMPL(user_access_add) { Req(env)->user.add_list(env[0]); }
205TOK_IMPL(user_access_rem) { Req(env)->user.rem_list(env[0]); }
206TOK_IMPL(user_fail_set) { Req(env)->user.fail()=env[0]; }
207TOK_IMPL(user_pin_set) { Req(env)->user.pin()=env[0]; }
208TOK_IMPL(user_alias_set) { Req(env)->user.alias()=env[0]; }
209TOK_IMPL(user_emails_set) { Req(env)->user.email()=env[0]; }
210TOK_IMPL(user_name_set) { Req(env)->user.name()=env[0]; }
211TOK_IMPL(user_last_set) { Req(env)->user.last()=env[0]; }
212TOK_IMPL(user_lastin_set) { Req(env)->user.lastin()=env[0]; }
213
214//////////////////////////////////////////////////////////
215
216TOK_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
233TOK_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
254void 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}