21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
|
local ctlcmds = {
{ 'start', 'start a new instance of the server' };
{ 'stop', 'stop a running instance' };
{ 'ls', 'list all running instances' };
{ 'attach', 'capture log output from a running instance' };
{ 'db', 'set up and manage the database' };
{ 'user', 'manage users, privileges, and credentials'};
{ 'mkroot <handle>', 'establish a new root user with the given handle' };
{ 'actor <xid> purge-all', 'remove all traces of a user from the database (except local user credentials -- use \27[1mauth all purge\27[m to prevent a user from accessing the instance)' };
{ 'actor <xid> create', 'instantiate a new actor' };
{ 'actor <xid> bestow <epithet>', 'bestow an epithet upon an actor' };
{ 'conf', 'manage the server configuration'};
{ 'serv dl', 'initiate an update cycle over foreign actors' };
{ 'tl', 'print the current local timeline to standard out' };
{ 'be pgsql setup-auth (managed|unmanaged)', '(PGSQL backends) select the authentication strategy to use' };
}
local cmdhelp = function(tbl)
local str = '\ncommands:\n'
................................................................................
if acks(i).success then
lib.report('instance #',num,' reports successful ',rep)
else
lib.report('instance #',num,' reports failed ',rep)
end
end
end
local emp = lib.ipc.global_emperor
local terra entry_mgtool(argc: int, argv: &rawstring): int
if argc < 1 then lib.bail('bad invocation!') end
lib.noise.init(2)
[lib.init]
................................................................................
return 1
end
if dbmode.arglist.ct < 1 then goto cmderr end
srv:setup(cnf)
if lib.str.cmp(dbmode.arglist(0),'init') == 0 and dbmode.arglist.ct == 2 then
lib.report('initializing new database structure for domain ', dbmode.arglist(1))
if dlg:dbsetup() then
srv:conprep(lib.store.prepmode.conf)
dlg:conf_set('instance-name', dbmode.arglist(1))
do var sec: int8[65] gensec(&sec[0])
dlg:conf_set('server-secret', &sec[0])
end
lib.report('database setup complete; use mkroot to create an administrative user')
else lib.bail('initialization process interrupted') end
elseif lib.str.cmp(dbmode.arglist(0),'obliterate') == 0 then
var confirmstrs = array(
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'eta', 'nu', 'kappa',
'emerald', 'carnelian', 'sapphire', 'ruby', 'amethyst'
)
var cfmstr: int8[64] cfmstr[0] = 0
var tdx = lib.osclock.time(nil) / 60
for i=0,3 do
if i ~= 0 then lib.str.cat(&cfmstr[0], '-') end
lib.str.cat(&cfmstr[0], confirmstrs[(tdx ^ (173*i)) % [confirmstrs.type.N]])
end
if dbmode.arglist.ct == 1 then
lib.bail('you are attempting to completely obliterate all data! make sure you have selected your target correctly. if you really want to do this, pass the confirmation string ', &cfmstr[0])
elseif dbmode.arglist.ct == 2 then
if lib.str.cmp(dbmode.arglist(1), cfmstr) == 0 then
lib.warn('completely obliterating all data!')
dlg:obliterate_everything()
................................................................................
dlg:conf_set('master',root.handle)
lib.report('created new administrator')
if mg then
var tmppw: int8[33]
pwset(dlg, &tmppw, ruid, false)
lib.report('temporary root pw: ', {&tmppw[0], 32})
end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'user') == 0 then
var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
if umode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' user ', umode.type.helptxt.flags, ' <handle> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'user <handle> auth <type> new', '(where applicable, managed auth only) create a new authentication token of the given type for a user' };
{ 'user <handle> auth <type> reset', '(where applicable, managed auth only) delete all of a user\'s authentication tokens of the given type and issue a new one' };
{ 'user <handle> auth (<type>|all) purge', 'delete all credentials that would allow this user to log in (where possible)' };
{ 'user <handle> (grant|revoke) (<priv>|all)', 'grant or revoke a specific power to or from a user' };
{ 'user <handle> emasculate', 'strip all administrative powers from a user' };
{ 'user <handle> forgive', 'restore all default powers to a user' };
{ 'user <handle> suspend [<timespec>]', '(e.g. \27[1muser jokester suspend 5d 6h 7m 3s\27[m to suspend "jokester" for five days, six hours, seven minutes, and three seconds) suspend a user'};
}) ]
return 1
end
if umode.arglist.ct >= 3 then
var grant = lib.str.cmp(umode.arglist(1),'grant') == 0
var handle = umode.arglist(0)
var usr = dlg:actor_fetch_xid(pstr {ptr=handle, ct=lib.str.sz(handle)})
if grant or lib.str.cmp(umode.arglist(1),'revoke') == 0 then
if not usr then lib.bail('unknown handle') end
var newprivs = usr.ptr.rights.powers
var map = array([lib.store.privmap])
if umode.arglist.ct == 3 and lib.str.cmp(umode.arglist(2),'all') == 0 then
if grant
then newprivs:fill()
else newprivs:clear()
end
|
|
>
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<
<
<
<
|
<
<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
|
|
>
>
>
>
>
>
>
>
>
>
|
|
>
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
|
local ctlcmds = {
{ 'start', 'start a new instance of the server' };
{ 'stop', 'stop a running instance' };
{ 'ls', 'list all running instances' };
{ 'attach', 'capture log output from a running instance' };
{ 'db', 'set up and manage the database' };
{ 'user', 'create and manage users, privileges, and credentials'};
{ 'actor', 'manage and purge actors, epithets, and ranks'};
{ 'mkroot <handle>', 'establish a new root user with the given handle' };
{ 'conf', 'manage the server configuration'};
{ 'grow <count> [<acl>]', 'grant a new round of invites to all users, or those who match the given ACL' };
{ 'serv dl', 'initiate an update cycle over foreign actors' };
{ 'tl', 'print the current local timeline to standard out' };
{ 'be pgsql setup-auth (managed|unmanaged)', '(PGSQL backends) select the authentication strategy to use' };
}
local cmdhelp = function(tbl)
local str = '\ncommands:\n'
................................................................................
if acks(i).success then
lib.report('instance #',num,' reports successful ',rep)
else
lib.report('instance #',num,' reports failed ',rep)
end
end
end
local terra gen_cfstr(cfmstr: rawstring, seed: intptr)
var confirmstrs = array(
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'eta', 'nu', 'kappa',
'emerald', 'carnelian', 'sapphire', 'ruby', 'amethyst'
)
var tdx = lib.osclock.time(nil) / 60
cfmstr[0] = 0
for i=0,3 do
if i ~= 0 then lib.str.cat(cfmstr, '-') end
lib.str.cat(cfmstr, confirmstrs[(seed ^ tdx ^ (173*i)) % [confirmstrs.type.N]])
end
end
local emp = lib.ipc.global_emperor
local terra entry_mgtool(argc: int, argv: &rawstring): int
if argc < 1 then lib.bail('bad invocation!') end
lib.noise.init(2)
[lib.init]
................................................................................
return 1
end
if dbmode.arglist.ct < 1 then goto cmderr end
srv:setup(cnf)
if lib.str.cmp(dbmode.arglist(0),'init') == 0 and dbmode.arglist.ct == 2 then
lib.report('initializing new database structure for domain ', dbmode.arglist(1))
dlg:tx_enter()
if dlg:dbsetup() then
srv:conprep(lib.store.prepmode.conf)
dlg:conf_set('instance-name', dbmode.arglist(1))
dlg:conf_set('domain', dbmode.arglist(1))
do var sec: int8[65] gensec(&sec[0])
dlg:conf_set('server-secret', &sec[0])
dlg:conf_set('server-secret', &sec[0])
end
lib.report('database setup complete; use mkroot to create an administrative user')
else lib.bail('initialization process interrupted') end
dlg:tx_complete()
elseif lib.str.cmp(dbmode.arglist(0),'obliterate') == 0 then
var cfmstr: int8[64] gen_cfstr(&cfmstr[0],0)
if dbmode.arglist.ct == 1 then
lib.bail('you are attempting to completely obliterate all data! make sure you have selected your target correctly. if you really want to do this, pass the confirmation string ', &cfmstr[0])
elseif dbmode.arglist.ct == 2 then
if lib.str.cmp(dbmode.arglist(1), cfmstr) == 0 then
lib.warn('completely obliterating all data!')
dlg:obliterate_everything()
................................................................................
dlg:conf_set('master',root.handle)
lib.report('created new administrator')
if mg then
var tmppw: int8[33]
pwset(dlg, &tmppw, ruid, false)
lib.report('temporary root pw: ', {&tmppw[0], 32})
end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'actor') == 0 then
var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
if umode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' actor ', umode.type.helptxt.flags, ' <xid> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'actor <xid> rank <value>', 'set an actor\'s rank to <value> (remote actors cannot exercise rank-related powers, but benefit from rank immunities)' };
{ 'actor <xid> degrade', 'alias for `actor <xid> rank 0`' };
{ 'actor <xid> bestow <epithet>', 'bestow an epithet upon an actor' };
{ 'actor <xid> instantiate', 'instantiate a remote actor, retrieving their profile and posts even if no one follows them' };
{ 'actor <xid> proscribe', 'globally ban an actor from interacting with your server' };
{ 'actor <xid> rehabilitate', 'lift a proscription on an actor' };
{ 'actor <xid> purge-all <confirm-str>', 'remove all traces of a user from the database (except local user credentials -- use \27[1mauth all purge\27[m to prevent a user from accessing the instance)' };
}) ]
return 1
end
if umode.arglist.ct >= 2 then
var degrade = lib.str.cmp(umode.arglist(1),'degrade') == 0
var xid = umode.arglist(0)
var usr = dlg:actor_fetch_xid(pstr {ptr=xid, ct=lib.str.sz(xid)})
if not usr then lib.bail('no such actor') end
if degrade or lib.str.cmp(umode.arglist(1),'rank') == 0 then
var rank: uint16
if degrade and umode.arglist.ct == 2 then
rank = 0
elseif (not degrade) and umode.arglist.ct == 3 then
var r, ok = lib.math.decparse(pstr {
ptr = umode.arglist(2);
ct = lib.str.sz(umode.arglist(2));
})
if not ok then goto cmderr end
rank = r
else goto cmderr end
usr.ptr.rights.rank = rank
dlg:actor_save(usr.ptr)
lib.report('set user rank')
elseif umode.arglist.ct == 3 and lib.str.cmp(umode.arglist(1),'bestow') == 0 then
if umode.arglist(2)[0] == 0
then usr.ptr.epithet = nil
else usr.ptr.epithet = umode.arglist(2)
end
dlg:actor_save(usr.ptr)
lib.report('bestowed a new epithet on ', usr.ptr.xid)
elseif lib.str.cmp(umode.arglist(1),'purge-all') == 0 then
var cfmstr: int8[64] gen_cfstr(&cfmstr[0],usr.ptr.id)
if umode.arglist.ct == 2 then
lib.bail('you are attempting to completely purge the actor ', usr.ptr.xid, ' and all related content from the database! if you really want to do this, pass the confirmation string ', &cfmstr[0])
elseif umode.arglist.ct == 3 then
if lib.str.ncmp(&cfmstr[0],umode.arglist(2),64) ~= 0 then
lib.bail('you have supplied an invalid confirmation string; if you really want to purge this actor, pass ', &cfmstr[0])
end
lib.warn('completely purging actor ', usr.ptr.xid, ' and all related content from database')
dlg:actor_purge_uid(usr.ptr.id)
lib.report('actor purged')
else goto cmderr end
else goto cmderr end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'user') == 0 then
var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
if umode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' user ', umode.type.helptxt.flags, ' <handle> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'user <handle> create', 'add a new user' };
{ 'user <handle> auth <type> new', '(where applicable, managed auth only) create a new authentication token of the given type for a user' };
{ 'user <handle> auth <type> reset', '(where applicable, managed auth only) delete all of a user\'s authentication tokens of the given type and issue a new one' };
{ 'user <handle> auth (<type>|all) purge', 'delete all credentials that would allow this user to log in (where possible)' };
{ 'user <handle> (grant|revoke) (<priv>|all)', 'grant or revoke a specific power to or from a user' };
{ 'user <handle> emasculate', 'strip all administrative powers and rank from a user' };
{ 'user <handle> forgive', 'restore all default powers to a user' };
{ 'user <handle> suspend [<timespec>]', '(e.g. \27[1muser jokester suspend 5d 6h 7m 3s\27[m to suspend "jokester" for five days, six hours, seven minutes, and three seconds) suspend a user'};
}) ]
return 1
end
var handle = umode.arglist(0)
var usr = dlg:actor_fetch_xid(pstr {ptr=handle, ct=lib.str.sz(handle)})
if umode.arglist.ct == 2 and lib.str.cmp(umode.arglist(1),'create')==0 then
if usr:ref() then lib.bail('that user already exists') end
if not lib.store.actor.handle_validate(handle) then
lib.bail('invalid user handle') end
var kbuf: uint8[lib.crypt.const.maxdersz]
var na = lib.store.actor.mk(&kbuf[0])
na.handle = handle
dlg:actor_create(&na)
lib.report('created new user @',na.handle,'; assign credentials to enable login')
elseif umode.arglist.ct >= 3 then
var grant = lib.str.cmp(umode.arglist(1),'grant') == 0
if not usr then lib.bail('no such user') end
if grant or lib.str.cmp(umode.arglist(1),'revoke') == 0 then
var newprivs = usr.ptr.rights.powers
var map = array([lib.store.privmap])
if umode.arglist.ct == 3 and lib.str.cmp(umode.arglist(2),'all') == 0 then
if grant
then newprivs:fill()
else newprivs:clear()
end
|