parsav  Diff

Differences From Artifact [293667feb7]:

To Artifact [54eca1a845]:


    27     27   	{ 'db extract (<artifact>|<post>/<attachment number>)', 'extracts an attachment artifact from the database and prints it to standard out' };
    28     28   	{ 'db excise <artifact>', 'extracts an attachment artifact from the database and prints it to standard out' };
    29     29   	{ 'db obliterate', 'completely purge all parsav-related content and structure from the database, destroying all user content (requires confirmation)' };
    30     30   	{ 'db insert', 'reads a file from standard in and inserts it into the attachment database, printing the resulting ID' };
    31     31   	{ 'mkroot <handle>', 'establish a new root user with the given handle' };
    32     32   	{ 'user <handle> auth <type> new', '(where applicable, managed auth only) create a new authentication token of the given type for a user' };
    33     33   	{ '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' };
    34         -	{ 'user <handle> auth purge-credentials [<type>]', 'delete all credentials that would allow this user to log in (where possible)' };
           34  +	{ 'user <handle> auth (<type>|all) purge', 'delete all credentials that would allow this user to log in (where possible)' };
    35     35   	{ 'user <handle> (grant|revoke) (<priv>|all)', 'grant or revoke a specific power to or from a user' };
    36     36   	{ 'user <handle> emasculate', 'strip all administrative powers from a user' };
    37     37   	{ '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'};
    38         -	{ 'actor <xid> purge-all', 'remove all traces of a user from the database (except local user credentials -- use \27[1mauth purge-credentials\27[m to prevent a user from accessing the instance)' };
           38  +	{ '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)' };
    39     39   	{ 'actor <xid> create', 'instantiate a new actor' };
    40     40   	{ 'actor <xid> bestow <epithet>', 'bestow an epithet upon an actor' };
    41     41   	{ 'conf set <setting> <value>', 'add or a change a server configuration parameter to the database' };
    42     42   	{ 'conf get <setting>', 'report the value of a server setting' };
    43     43   	{ 'conf reset <setting>', 'reset a server setting to its default value' };
    44     44   	{ 'conf refresh', 'instruct an instance to refresh its configuration cache' };
    45     45   	{ 'conf chsec', 'reset the server secret, invalidating all authentication cookies' };
................................................................................
    81     81   
    82     82   local terra gensec(sdest: rawstring)
    83     83   	var dest = [&uint8](sdest)
    84     84   	lib.crypt.spray(dest,64)
    85     85   	for i=0,64 do dest[i] = dest[i] % (0x7e - 0x20) + 0x20 end
    86     86   	dest[64] = 0
    87     87   end
           88  +
           89  +local terra pwset(dlg: idelegate, buf: &(int8[33]), uid: uint64, reset: bool)
           90  +	lib.dbg('generating temporary password')
           91  +	var tmppw = [&uint8](&(buf[0]))
           92  +	lib.crypt.spray(tmppw,32) tmppw[32] = 0
           93  +	for i=0,32 do
           94  +		tmppw[i] = tmppw[i] % (10 + 26*2)
           95  +		if tmppw[i] >= 36 then
           96  +			tmppw[i] = tmppw[i] + (0x61 - 36)
           97  +		elseif tmppw[i] >= 10 then
           98  +			tmppw[i] = tmppw[i] + (0x41 - 10)
           99  +		else tmppw[i] = tmppw[i] + 0x30 end
          100  +	end
          101  +	lib.dbg('assigning temporary password')
          102  +	dlg:auth_create_pw(uid, reset, pstr {
          103  +		ptr = [rawstring](tmppw), ct = 32
          104  +	})
          105  +end
    88    106   
    89    107   local terra entry_mgtool(argc: int, argv: &rawstring): int
    90    108   	if argc < 1 then lib.bail('bad invocation!') end
    91    109   
    92    110   	lib.noise_init(2)
    93    111   	[lib.init]
    94    112   
................................................................................
   219    237   					root.epithet = epithets[lib.crypt.random(intptr,0,[epithets.type.N])]
   220    238   					root.rights.powers:fill() -- grant omnipotence
   221    239   					root.rights.rank = 1
   222    240   					var ruid = dlg:actor_create(&root)
   223    241   					dlg:conf_set('master',root.handle)
   224    242   					lib.report('created new administrator')
   225    243   					if mg then
   226         -						lib.dbg('generating temporary password')
   227         -						var tmppw: uint8[33]
   228         -						lib.crypt.spray(&tmppw[0],32) tmppw[32] = 0
   229         -						for i=0,32 do
   230         -							tmppw[i] = tmppw[i] % (10 + 26*2)
   231         -							if tmppw[i] >= 36 then
   232         -								tmppw[i] = tmppw[i] + (0x61 - 36)
   233         -							elseif tmppw[i] >= 10 then
   234         -								tmppw[i] = tmppw[i] + (0x41 - 10)
   235         -							else tmppw[i] = tmppw[i] + 0x30 end
   236         -						end
   237         -						lib.dbg('assigning temporary password')
   238         -						dlg:auth_create_pw(ruid, false, pstr {
   239         -							ptr = [rawstring](&tmppw[0]), ct = 32
   240         -						})
   241         -						lib.report('temporary root pw: ', {[rawstring](&tmppw[0]), 32})
          244  +						var tmppw: int8[33]
          245  +						pwset(dlg, &tmppw, ruid, false)
          246  +						lib.report('temporary root pw: ', {&tmppw[0], 32})
   242    247   					end
   243    248   				else goto cmderr end
   244    249   			elseif lib.str.cmp(mode.arglist(0),'user') == 0 then
          250  +				var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
          251  +				if umode.help then
          252  +					[ lib.emit(false, 1, 'usage: ', `argv[0], ' user ', umode.type.helptxt.flags, ' <handle> <cmd> [<args>…]', umode.type.helptxt.opts) ]
          253  +					return 1
          254  +				end
          255  +				if umode.arglist.ct >= 3 then
          256  +					var grant = lib.str.cmp(umode.arglist(1),'grant') == 0
          257  +					var handle = umode.arglist(0)
          258  +					var usr = dlg:actor_fetch_xid(pstr {ptr=handle, ct=lib.str.sz(handle)})
          259  +					if not usr then lib.bail('unknown handle') end
          260  +					if grant or lib.str.cmp(umode.arglist(1),'revoke') == 0 then
          261  +						var newprivs = usr.ptr.rights.powers
          262  +						var map = array([lib.store.privmap])
          263  +						if umode.arglist.ct == 3 and lib.str.cmp(umode.arglist(2),'all') == 0 then
          264  +							if grant
          265  +								then newprivs:fill()
          266  +								else newprivs:clear()
          267  +							end
          268  +						else
          269  +							for i=2,umode.arglist.ct do
          270  +								var priv = umode.arglist(i)
          271  +								for j=0,[map.type.N] do
          272  +									var p = map[j]
          273  +									if p.name:cmp_raw(priv) then
          274  +										if grant then
          275  +											lib.dbg('enabling power ', {p.name.ptr,p.name.ct})
          276  +											newprivs = newprivs + p.priv
          277  +										else
          278  +											lib.dbg('disabling power ', {p.name.ptr,p.name.ct})
          279  +											newprivs = newprivs - p.priv
          280  +										end
          281  +										break
          282  +									end
          283  +								end
          284  +							end
          285  +						end
          286  +
          287  +						usr.ptr.rights.powers = newprivs
          288  +						dlg:actor_save_privs(usr.ptr)
          289  +					elseif lib.str.cmp(umode.arglist(1),'auth') == 0 and umode.arglist.ct == 4 then
          290  +						var reset = lib.str.cmp(umode.arglist(3),'reset') == 0
          291  +						if reset or lib.str.cmp(umode.arglist(3),'new') == 0 then
          292  +							if lib.str.cmp(umode.arglist(2),'pw') == 0 then
          293  +								var tmppw: int8[33]
          294  +								pwset(dlg, &tmppw, usr.ptr.id, reset)
          295  +								lib.report('new temporary password for ',usr.ptr.handle,': ', {&tmppw[0], 32})
          296  +							else lib.bail('unknown credential type') end
          297  +						elseif lib.str.cmp(umode.arglist(3),'purge') == 0 then
          298  +						else goto cmderr end
          299  +					else goto cmderr end
          300  +				else goto cmderr end
   245    301   			elseif lib.str.cmp(mode.arglist(0),'actor') == 0 then
   246    302   			elseif lib.str.cmp(mode.arglist(0),'tl') == 0 then
   247    303   			elseif lib.str.cmp(mode.arglist(0),'serv') == 0 then
   248    304   			else goto cmderr end
   249    305   		end
   250    306   	end
   251    307   
   252    308   	do return 0 end
   253         -	::cmderr:: lib.bail('invalid command') return 2
          309  +	::cmderr:: lib.bail('invalid command')
   254    310   end
   255    311   
   256    312   return entry_mgtool