XRootD
XrdAccConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d A c c C o n f i g . c c */
4 /* */
5 /* (C) 2003 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <unistd.h>
32 #include <cctype>
33 #include <fcntl.h>
34 #include <map>
35 #include <strings.h>
36 #include <cstdio>
37 #include <ctime>
38 #include <sys/param.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 
42 #include "XrdOuc/XrdOucLock.hh"
43 #include "XrdOuc/XrdOucEnv.hh"
44 #include "XrdOuc/XrdOucUri.hh"
45 #include "XrdSys/XrdSysError.hh"
46 #include "XrdSys/XrdSysHeaders.hh"
47 #include "XrdOuc/XrdOucStream.hh"
48 #include "XrdAcc/XrdAccAccess.hh"
49 #include "XrdAcc/XrdAccAudit.hh"
50 #include "XrdAcc/XrdAccConfig.hh"
51 #include "XrdAcc/XrdAccGroups.hh"
53 
54 /******************************************************************************/
55 /* G l o b a l C o n f i g u r a t i o n O b j e c t */
56 /******************************************************************************/
57 
58 // The following is the single configuration object. Other objects needing
59 // access to this object should simply declare an extern to it.
60 //
62 
63 /******************************************************************************/
64 /* d e f i n e s */
65 /******************************************************************************/
66 
67 #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(Config,Eroute);
68 
69 #define TS_Str(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
70 
71 #define TS_Chr(x,m) if (!strcmp(x,var)) {m = val[0]; return 0;}
72 
73 #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; return 0;}
74 
75 #define ACC_PGO 0x0001
76 
77 /******************************************************************************/
78 /* E x t e r n a l F u n c t i o n s */
79 /******************************************************************************/
80 /******************************************************************************/
81 /* o o a c c _ C o n f i g _ R e f r e s h */
82 /******************************************************************************/
83 
84 void *XrdAccConfig_Refresh( void *start_data )
85 {
86  XrdSysError *Eroute = (XrdSysError *)start_data;
87 
88 // Get the number of seconds between refreshes
89 //
90  struct timespec naptime = {(time_t)XrdAccConfiguration.AuthRT, 0};
91 
92 // Now loop until the bitter end
93 //
94  while(1)
95  {nanosleep(&naptime, 0); XrdAccConfiguration.ConfigDB(1, *Eroute);}
96  return (void *)0;
97 }
98 
99 /******************************************************************************/
100 /* C o n s t r u c t o r */
101 /******************************************************************************/
102 
104 {
105 
106 // Initialize path value and databse pointer to nil
107 //
108  dbpath = strdup("/opt/xrd/etc/Authfile");
109  Database = 0;
110  Authorization = 0;
111  spChar = 0;
112  uriPath = false;
113 
114 // Establish other defaults
115 //
116  ConfigDefaults();
117 }
118 
119 /******************************************************************************/
120 /* C o n f i g u r e */
121 /******************************************************************************/
122 
123 int XrdAccConfig::Configure(XrdSysError &Eroute, const char *cfn) {
124 /*
125  Function: Establish default values using a configuration file.
126 
127  Input: None.
128 
129  Output: 0 upon success or !0 otherwise.
130 */
131  char *var;
132  int retc, NoGo = 0, Cold = (Database == 0);
133  pthread_t reftid;
134 
135 // Print warm-up message
136 //
137  Eroute.Say("++++++ Authorization system initialization started.");
138 
139 // Process the configuration file and authorization database
140 //
141  if (!(Authorization = new XrdAccAccess(&Eroute))
142  || (NoGo = ConfigFile(Eroute, cfn))
143  || (NoGo = ConfigDB(0, Eroute)))
144  {if (Authorization) {delete Authorization, Authorization = 0;}
145  NoGo = 1;
146  }
147 
148 // Start a refresh thread unless this was a refresh thread call
149 //
150  if (Cold && !NoGo)
151  {if ((retc=XrdSysThread::Run(&reftid,XrdAccConfig_Refresh,(void *)&Eroute)))
152  Eroute.Emsg("ConfigDB",retc,"start refresh thread.");
153  }
154 
155 // All done
156 //
157  var = (NoGo > 0 ? (char *)"failed." : (char *)"completed.");
158  Eroute.Say("------ Authorization system initialization ", var);
159  return (NoGo > 0);
160 }
161 
162 /******************************************************************************/
163 /* C o n f i g D B */
164 /******************************************************************************/
165 
166 int XrdAccConfig::ConfigDB(int Warm, XrdSysError &Eroute)
167 {
168 /*
169  Function: Establish default values using a configuration file.
170 
171  Input: None.
172 
173  Output: 0 upon success or !0 otherwise.
174 */
175  char buff[128];
176  int retc, anum = 0, NoGo = 0;
177  struct XrdAccAccess_Tables tabs;
178  XrdOucLock cdb_Lock(&Config_Context);
179 
180 // Indicate type of start we are doing
181 //
182  if (!Database) NoGo = !(Database = XrdAccAuthDBObject(&Eroute));
183  else if (Warm && !Database->Changed(dbpath)) return 0;
184 
185 // Try to open the authorization database
186 //
187  if (!Database || !Database->Open(Eroute, dbpath)) return 1;
188 
189 // Allocate new hash tables
190 //
191  if (!(tabs.G_Hash = new XrdOucHash<XrdAccCapability>()) ||
192  !(tabs.H_Hash = new XrdOucHash<XrdAccCapability>()) ||
193  !(tabs.N_Hash = new XrdOucHash<XrdAccCapability>()) ||
194  !(tabs.O_Hash = new XrdOucHash<XrdAccCapability>()) ||
195  !(tabs.R_Hash = new XrdOucHash<XrdAccCapability>()) ||
196  !(tabs.T_Hash = new XrdOucHash<XrdAccCapability>()) ||
197  !(tabs.U_Hash = new XrdOucHash<XrdAccCapability>()) )
198  {Eroute.Emsg("ConfigDB","Insufficient storage for id tables.");
199  Database->Close(); return 1;
200  }
201 
202 // Now start processing records until eof.
203 //
204  rulenum = 0;
205  while((retc = ConfigDBrec(Eroute, tabs))) {NoGo |= retc < 0; anum++;}
206  snprintf(buff, sizeof(buff), "%d auth entries processed in ", anum);
207  Eroute.Say("Config ", buff, dbpath);
208 
209 // All done, close the database and return if we failed
210 //
211  if (!Database->Close() || NoGo) return 1;
212 
213 // Do final setup for special identifiers (this will correctly order them)
214 //
215  if (tabs.SYList) idChk(Eroute, tabs.SYList, tabs);
216 
217 // Set the access control tables
218 //
219  if (!tabs.G_Hash->Num()) {delete tabs.G_Hash; tabs.G_Hash=0;}
220  if (!tabs.H_Hash->Num()) {delete tabs.H_Hash; tabs.H_Hash=0;}
221  if (!tabs.N_Hash->Num()) {delete tabs.N_Hash; tabs.N_Hash=0;}
222  if (!tabs.O_Hash->Num()) {delete tabs.O_Hash; tabs.O_Hash=0;}
223  if (!tabs.R_Hash->Num()) {delete tabs.R_Hash; tabs.R_Hash=0;}
224  if (!tabs.T_Hash->Num()) {delete tabs.T_Hash; tabs.T_Hash=0;}
225  if (!tabs.U_Hash->Num()) {delete tabs.U_Hash; tabs.U_Hash=0;}
226  Authorization->SwapTabs(tabs);
227 
228 // All done
229 //
230  return NoGo;
231 }
232 
233 /******************************************************************************/
234 /* P r i v a t e F u n c t i o n s */
235 /******************************************************************************/
236 /******************************************************************************/
237 /* C o n f i g F i l e P r o c e s s i n g M e t h o d s */
238 /******************************************************************************/
239 
240 int XrdAccConfig::ConfigFile(XrdSysError &Eroute, const char *ConfigFN) {
241 /*
242  Function: Establish default values using a configuration file.
243 
244  Input: None.
245 
246  Output: 1 - Processing failed.
247  0 - Processing completed successfully.
248  -1 = Security is to be disabled by request.
249 */
250  char *var;
251  int cfgFD, retc, NoGo = 0, recs = 0;
252  XrdOucEnv myEnv;
253  XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> ");
254 
255 // If there is no config file, complain
256 //
257  if( !ConfigFN || !*ConfigFN)
258  {Eroute.Emsg("Config", "Authorization configuration file not specified.");
259  return 1;
260  }
261 
262 // Check if security is to be disabled
263 //
264  if (!strcmp(ConfigFN, "none"))
265  {Eroute.Emsg("Config", "Authorization system deactivated.");
266  return -1;
267  }
268 
269 // Try to open the configuration file.
270 //
271  if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
272  {Eroute.Emsg("Config", errno, "open config file", ConfigFN);
273  return 1;
274  }
275  Eroute.Emsg("Config","Authorization system using configuration in",ConfigFN);
276 
277 // Now start reading records until eof.
278 //
279  ConfigDefaults(); Config.Attach(cfgFD); Config.Tabs(0);
280  static const char *cvec[] = { "*** acc plugin config:", 0 };
281  Config.Capture(cvec);
282 
283  while((var = Config.GetMyFirstWord()))
284  {if (!strncmp(var, "acc.", 2))
285  {recs++;
286  if (ConfigXeq(var+4, Config, Eroute)) {Config.Echo(); NoGo = 1;}
287  }
288  }
289 
290 // Now check if any errors occurred during file i/o
291 //
292  if ((retc = Config.LastError()))
293  NoGo = Eroute.Emsg("Config",-retc,"read config file",ConfigFN);
294  else {char buff[128];
295  snprintf(buff, sizeof(buff),
296  "%d authorization directives processed in ", recs);
297  Eroute.Say("Config ", buff, ConfigFN);
298  }
299  Config.Close();
300 
301 // Set external options, as needed
302 //
303  if (options & ACC_PGO) GroupMaster.SetOptions(Primary_Only);
304 
305 // All done
306 //
307  return NoGo;
308 }
309 
310 /******************************************************************************/
311 /* C o n f i g D e f a u l t s */
312 /******************************************************************************/
313 
314 void XrdAccConfig::ConfigDefaults()
315 {
316  AuthRT = 60*60*12;
317  options = 0;
318 }
319 
320 /******************************************************************************/
321 /* C o n f i g X e q */
322 /******************************************************************************/
323 
324 int XrdAccConfig::ConfigXeq(char *var, XrdOucStream &Config, XrdSysError &Eroute)
325 {
326 
327 // Fan out based on the variable
328 //
329  TS_Xeq("audit", xaud);
330  TS_Xeq("authdb", xdbp);
331  TS_Xeq("authrefresh", xart);
332  TS_Xeq("encoding", xenc);
333  TS_Xeq("gidlifetime", xglt);
334  TS_Xeq("gidretran", xgrt);
335  TS_Xeq("nisdomain", xnis);
336  TS_Bit("pgo", options, ACC_PGO);
337  TS_Xeq("spacechar", xspc);
338 
339 // No match found, complain.
340 //
341  Eroute.Emsg("Config", "unknown directive", var);
342  Config.Echo();
343  return 1;
344 }
345 
346 /******************************************************************************/
347 /* s u b S p a c e */
348 /******************************************************************************/
349 
350 void XrdAccConfig::subSpace(char *id)
351 {
352  char *spc;
353 
354  while((spc = index(id, spChar)))
355  {*spc = ' ';
356  id = spc+1;
357  }
358 }
359 
360 /******************************************************************************/
361 /* x a u d */
362 /******************************************************************************/
363 
364 /* Function: xaud
365 
366  Purpose: To parse the directive: audit <options>
367 
368  options:
369 
370  deny audit access denials.
371  grant audit access grants.
372  none audit is disabled.
373 
374  Output: 0 upon success or !0 upon failure.
375 */
376 
377 int XrdAccConfig::xaud(XrdOucStream &Config, XrdSysError &Eroute)
378 {
379  static struct auditopts {const char *opname; int opval;} audopts[] =
380  {
381  {"deny", (int)audit_deny},
382  {"grant", (int)audit_grant}
383  };
384  int i, audval = 0, numopts = sizeof(audopts)/sizeof(struct auditopts);
385  char *val;
386 
387  val = Config.GetWord();
388  if (!val || !val[0])
389  {Eroute.Emsg("Config", "audit option not specified"); return 1;}
390  while (val && val[0])
391  {if (!strcmp(val, "none")) audval = (int)audit_none;
392  else for (i = 0; i < numopts; i++)
393  {if (!strcmp(val, audopts[i].opname))
394  {audval |= audopts[i].opval; break;}
395  if (i >= numopts)
396  {Eroute.Emsg("Config","invalid audit option -",val);
397  return 1;
398  }
399  }
400  val = Config.GetWord();
401  }
402  Authorization->Auditor->setAudit((XrdAccAudit_Options)audval);
403  return 0;
404 }
405 
406 /******************************************************************************/
407 /* x a r t */
408 /******************************************************************************/
409 
410 /* Function: xart
411 
412  Purpose: To parse the directive: authrefresh <seconds>
413 
414  <seconds> minimum number of seconds between aythdb refreshes.
415 
416  Output: 0 upon success or !0 upon failure.
417 */
418 
419 int XrdAccConfig::xart(XrdOucStream &Config, XrdSysError &Eroute)
420 {
421  char *val;
422  int reft;
423 
424  val = Config.GetWord();
425  if (!val || !val[0])
426  {Eroute.Emsg("Config","authrefresh value not specified");return 1;}
427  if (XrdOuca2x::a2tm(Eroute,"authrefresh value",val,&reft,60))
428  return 1;
429  AuthRT = reft;
430  return 0;
431 }
432 
433 /******************************************************************************/
434 /* x e n c */
435 /******************************************************************************/
436 
437 /* Function: xenc
438 
439  Purpose: To parse the directive: encoding [space <char>] [pct path]
440 
441  <char> the character that is to be considred as a space.
442  This only applies to identifiers.
443 
444  Output: 0 upon success or !0 upon failure.
445 */
446 
447 int XrdAccConfig::xenc(XrdOucStream &Config, XrdSysError &Eroute)
448 {
449  char *val;
450 
451  if (!(val = Config.GetWord()) || *val == 0)
452  {Eroute.Emsg("Config","encoding argument not specified"); return 1;}
453 
454 do{ if (!strcmp(val, "pct"))
455  {if (!(val = Config.GetWord()))
456  {Eroute.Emsg("Config","pct argument not specified");
457  return 1;
458  }
459  if (strcmp(val, "path"))
460  {Eroute.Emsg("Config",val, "pct encoding not supported");
461  return 1;
462  }
463  uriPath = true;
464  }
465  else if (!strcmp(val, "space"))
466  {if (!(val = Config.GetWord()))
467  {Eroute.Emsg("Config","space argument not specified");
468  return 1;
469  }
470  if (strlen(val) != 1)
471  {Eroute.Emsg("Config","invalid space argument -", val);
472  return 1;
473  }
474  spChar = *val;
475  }
476  } while((val = Config.GetWord()) && *val);
477 
478 
479  return 0;
480 }
481 
482 /******************************************************************************/
483 /* x d b p */
484 /******************************************************************************/
485 
486 /* Function: xdbp
487 
488  Purpose: To parse the directive: authdb <path>
489 
490  <path> is the path to the authorization database.
491 
492  Output: 0 upon success or !0 upon failure.
493 */
494 
495 int XrdAccConfig::xdbp(XrdOucStream &Config, XrdSysError &Eroute)
496 {
497  char *val;
498 
499  val = Config.GetWord();
500  if (!val || !val[0])
501  {Eroute.Emsg("Config","authdb path not specified");return 1;}
502  dbpath = strdup(val);
503  return 0;
504 }
505 
506 /******************************************************************************/
507 /* x g l t */
508 /******************************************************************************/
509 
510 /* Function: xglt
511 
512  Purpose: To parse the directive: gidlifetime <seconds>
513 
514  <seconds> maximum number of seconds to cache gid information.
515 
516  Output: 0 upon success or !0 upon failure.
517 */
518 
519 int XrdAccConfig::xglt(XrdOucStream &Config, XrdSysError &Eroute)
520 {
521  char *val;
522  int reft;
523 
524  val = Config.GetWord();
525  if (!val || !val[0])
526  {Eroute.Emsg("Config","gidlifetime value not specified");return 1;}
527  if (XrdOuca2x::a2tm(Eroute,"gidlifetime value",val,&reft,60))
528  return 1;
529  GroupMaster.SetLifetime(reft);
530  return 0;
531 }
532 
533 /******************************************************************************/
534 /* x g r t */
535 /******************************************************************************/
536 
537 /* Function: xgrt
538 
539  Purpose: To parse the directive: gidretran <gidlist>
540 
541  <gidlist> is a list of blank separated gid's that must be
542  retranslated.
543 
544  Output: 0 upon success or !0 upon failure.
545 */
546 
547 int XrdAccConfig::xgrt(XrdOucStream &Config, XrdSysError &Eroute)
548 {
549  char *val;
550  int gid;
551 
552  val = Config.GetWord();
553  if (!val || !val[0])
554  {Eroute.Emsg("Config","gidretran value not specified"); return 1;}
555 
556  while (val && val[0])
557  {if (XrdOuca2x::a2i(Eroute, "gid", val, &gid, 0)) return 1;
558  if (GroupMaster.Retran((gid_t)gid) < 0)
559  {Eroute.Emsg("Config", "to many gidretran gid's"); return 1;}
560  val = Config.GetWord();
561  }
562  return 0;
563 }
564 
565 /******************************************************************************/
566 /* x n i s */
567 /******************************************************************************/
568 
569 /* Function: xnis
570 
571  Purpose: To parse the directive: nisdomain <domain>
572 
573  <domain> the NIS domain to be used for nis look-ups.
574 
575  Output: 0 upon success or !0 upon failure.
576 */
577 
578 int XrdAccConfig::xnis(XrdOucStream &Config, XrdSysError &Eroute)
579 {
580  char *val;
581 
582  val = Config.GetWord();
583  if (!val || !val[0])
584  {Eroute.Emsg("Config","nisdomain value not specified");return 1;}
585  GroupMaster.SetDomain(strdup(val));
586  return 0;
587 }
588 
589 /******************************************************************************/
590 /* x s p c */
591 /******************************************************************************/
592 
593 /* Function: xspc (deprecated and undocumented, replaced by acc.encoding).
594 
595  Purpose: To parse the directive: spacechar <char>
596 
597  <char> the character that is to be considred as a space.
598 
599  Output: 0 upon success or !0 upon failure.
600 */
601 
602 int XrdAccConfig::xspc(XrdOucStream &Config, XrdSysError &Eroute)
603 {
604  char *val;
605 
606  val = Config.GetWord();
607  if (!val || !val[0])
608  {Eroute.Emsg("Config","spacechar argument not specified");return 1;}
609  if (strlen(val) != 1)
610  {Eroute.Emsg("Config","invalid spacechar argument -", val);return 1;}
611  spChar = *val;
612  return 0;
613 }
614 
615 /******************************************************************************/
616 /* D a t a b a s e P r o c e s s i n g */
617 /******************************************************************************/
618 /******************************************************************************/
619 /* C o n f i g D B r e c */
620 /******************************************************************************/
621 
622 int XrdAccConfig::ConfigDBrec(XrdSysError &Eroute,
623  struct XrdAccAccess_Tables &tabs)
624 {
625 // The following enum is here for convenience
626 //
627  enum DB_RecType { Group_ID = 'g',
628  Host_ID = 'h',
629  Netgrp_ID = 'n',
630  Org_ID = 'o',
631  Role_ID = 'r',
632  Set_ID = 's',
633  Template_ID = 't',
634  User_ID = 'u',
635  Xxx_ID = 'x',
636  Def_ID = '=',
637  No_ID = 0
638  };
639  char *authid, rtype, *path, *privs;
640  int alluser = 0, anyuser = 0, domname = 0, NoGo = 0;
641  DB_RecType rectype;
642  XrdAccAccess_ID *sp = 0;
645  XrdAccPrivCaps xprivs;
646  XrdAccCapability mycap((char *)"", xprivs), *currcap, *lastcap = &mycap;
647  XrdAccCapName *ncp;
648  bool istmplt, isDup, xclsv = false;
649 
650  // Prepare the next record in the database
651  //
652  if (!(rtype = Database->getRec(&authid))) return 0;
653  rectype = (DB_RecType)rtype;
654 
655  // Set up to handle the particular record
656  //
657  switch(rectype)
658  {case Group_ID: hp = tabs.G_Hash;
659  gtype=XrdAccUnixGroup;
660  if (spChar) subSpace(authid);
661  break;
662  case Host_ID: hp = tabs.H_Hash;
663  domname = (authid[0] == '.');
664  break;
665  case Set_ID: hp = 0;
666  break;
667  case Netgrp_ID: hp = tabs.N_Hash;
668  gtype=XrdAccNetGroup;
669  break;
670  case Org_ID: hp = tabs.O_Hash;
671  if (spChar) subSpace(authid);
672  break;
673  case Role_ID: hp = tabs.R_Hash;
674  if (spChar) subSpace(authid);
675  break;
676  case Template_ID: hp = tabs.T_Hash;
677  break;
678  case User_ID: hp = tabs.U_Hash;
679  alluser = (authid[0] == '*' && !authid[1]);
680  anyuser = (authid[0] == '=' && !authid[1]);
681  if (!alluser && !anyuser && spChar) subSpace(authid);
682  break;
683  case Xxx_ID: hp = 0; xclsv = true;
684  break;
685  case Def_ID: return idDef(Eroute, tabs, authid);
686  break;
687  default: char badtype[2] = {rtype, '\0'};
688  Eroute.Emsg("ConfigXeq", "Invalid id type -",
689  badtype);
690  return -1;
691  break;
692  }
693 
694  // Check if this id is already defined in the table. For 's' rules the id
695  // must have been previously defined.
696  //
697  if (domname)
698  isDup = tabs.D_List && tabs.D_List->Find((const char *)authid);
699  else if (alluser) isDup = tabs.Z_List != 0;
700  else if (anyuser) isDup = tabs.X_List != 0;
701  else if (hp) isDup = hp->Find(authid) != 0;
702  else {if (!(sp = tabs.S_Hash->Find(authid)))
703  {Eroute.Emsg("ConfigXeq", "Missing id definition -", authid);
704  return -1;
705  }
706  isDup = sp->caps != 0;
707  sp->rule = (xclsv ? rulenum++ : -1);
708  }
709 
710  if (isDup)
711  {Eroute.Emsg("ConfigXeq", "duplicate rule for id -", authid);
712  return -1;
713  }
714 
715  // Add this ID to the appropriate group object constants table
716  //
717  if (gtype) GroupMaster.AddName(gtype, (const char *)authid);
718 
719  // Now start getting <path> <priv> pairs until we hit the logical end
720  //
721  while(1) {NoGo = 0;
722  if (!Database->getPP(&path, &privs, istmplt)) break;
723  if (!path) continue; // Skip pathless entries
724  NoGo = 1;
725  if (istmplt)
726  {if ((currcap = tabs.T_Hash->Find(path)))
727  currcap = new XrdAccCapability(currcap);
728  else {Eroute.Emsg("ConfigXeq", "Missing template -", path);
729  break;
730  }
731  } else {
732  if (!privs)
733  {Eroute.Emsg("ConfigXeq", "Missing privs for path", path);
734  break;
735  }
736  if (!PrivsConvert(privs, xprivs))
737  {Eroute.Emsg("ConfigXeq", "Invalid privs -", privs);
738  break;
739  }
740  if (uriPath)
741  {int plen = strlen(path);
742  char *decp = (char *)alloca(plen+1);
743  XrdOucUri::Decode(path, plen, decp);
744  currcap = new XrdAccCapability(decp, xprivs);
745  } else currcap = new XrdAccCapability(path, xprivs);
746  }
747  lastcap->Add(currcap);
748  lastcap = currcap;
749  }
750 
751  // Check if all went well
752  //
753  if (NoGo) return -1;
754 
755  // Check if any capabilities were specified
756  //
757  if (!mycap.Next())
758  {Eroute.Emsg("ConfigXeq", "no capabilities specified for", authid);
759  return -1;
760  }
761 
762  // Insert the capability into the appropriate table/list
763  //
764  if (sp) sp->caps = mycap.Next();
765  else if (domname)
766  {if (!(ncp = new XrdAccCapName(authid, mycap.Next())))
767  {Eroute.Emsg("ConfigXeq","unable to add id",authid); return -1;}
768  if (tabs.E_List) tabs.E_List->Add(ncp);
769  else tabs.D_List = ncp;
770  tabs.E_List = ncp;
771  }
772  else if (anyuser) tabs.X_List = mycap.Next();
773  else if (alluser) tabs.Z_List = mycap.Next();
774  else hp->Add(authid, mycap.Next());
775 
776  // All done
777  //
778  mycap.Add((XrdAccCapability *)0);
779  return 1;
780 }
781 
782 /******************************************************************************/
783 /* Private: i d C h k */
784 /******************************************************************************/
785 
786 void XrdAccConfig::idChk(XrdSysError &Eroute,
787  XrdAccAccess_ID *idList,
788  XrdAccAccess_Tables &tabs)
789 {
790  std::map<int, XrdAccAccess_ID *> idMap;
791  XrdAccAccess_ID *idPN, *xList = 0, *yList = 0;
792 
793 // Run through the list to make everything was used. We also, sort these items
794 // in the order the associated rule appeared.
795 //
796  while(idList)
797  {idPN = idList->next;
798  if (idList->caps == 0)
799  Eroute.Say("Config ","Warning, unused identifier definition '",
800  idList->name, "'.");
801  else if (idList->rule >= 0) idMap[idList->rule] = idList;
802  else {idList->next = yList; yList = idList;}
803  idList = idPN;
804  }
805 
806 // Place 'x' rules in the order they were used. The ;s; rules are in the
807 // order the id's were defined which is OK because the are inclusive.
808 //
809  std::map<int,XrdAccAccess_ID *>::reverse_iterator rit;
810  for (rit = idMap.rbegin(); rit != idMap.rend(); ++rit)
811  {rit->second->next = xList;
812  xList = rit->second;
813  }
814 
815 // Set the new lists in the supplied tabs structure
816 //
817  tabs.SXList = xList;
818  tabs.SYList = yList;
819 }
820 
821 /******************************************************************************/
822 /* Private: i d D e f */
823 /******************************************************************************/
824 
825 int XrdAccConfig::idDef(XrdSysError &Eroute,
826  struct XrdAccAccess_Tables &tabs,
827  const char *idName)
828 {
829  XrdAccAccess_ID *xID, theID(idName);
830  char *idname, buff[80], idType;
831  bool haveID = false, idDup = false;
832 
833 // Now start getting <idtype> <idname> pairs until we hit the logical end
834 //
835  while(!idDup)
836  {if (!(idType = Database->getID(&idname))) break;
837  haveID = true;
838  switch(idType)
839  {case 'g': if (spChar) subSpace(idname);
840  if (theID.grp) idDup = true;
841  else{theID.grp = strdup(idname);
842  theID.glen = strlen(idname);
843  }
844  break;
845  case 'h': if (theID.host) idDup = true;
846  else{theID.host = strdup(idname);
847  theID.hlen = strlen(idname);
848  }
849  break;
850  case 'o': if (theID.org) idDup = true;
851  else {if (spChar) subSpace(idname);
852  theID.org = strdup(idname);
853  }
854  break;
855  case 'r': if (theID.role) idDup = true;
856  else {if (spChar) subSpace(idname);
857  theID.role = strdup(idname);
858  }
859  break;
860  case 'u': if (theID.user) idDup = true;
861  else {if (spChar) subSpace(idname);
862  theID.user = strdup(idname);
863  }
864  break;
865  default: snprintf(buff, sizeof(buff), "'%c: %s' for",
866  idType, idname);
867  Eroute.Emsg("ConfigXeq", "Invalid id selector -",
868  buff, theID.name);
869  return -1;
870  break;
871  }
872  if (idDup)
873  {snprintf(buff, sizeof(buff),
874  "id selector '%c' specified twice for", idType);
875  Eroute.Emsg("ConfigXeq", buff, theID.name);
876  return -1;
877  }
878  }
879 
880 // Make sure some kind of id was specified
881 //
882  if (!haveID)
883  {Eroute.Emsg("ConfigXeq", "No id selectors specified for", theID.name);
884  return -1;
885  }
886 
887 // Make sure this name has not been specified before
888 //
889  if (!tabs.S_Hash) tabs.S_Hash = new XrdOucHash<XrdAccAccess_ID>;
890  else if (tabs.S_Hash->Find(theID.name))
891  {Eroute.Emsg("ConfigXeq","duplicate id definition -",theID.name);
892  return -1;
893  }
894 
895 // Export the id definition and add it to the S_Hash
896 //
897  xID = theID.Export();
898  tabs.S_Hash->Add(xID->name, xID);
899 
900 // Place this FIFO in SYList (they reordered later based on rule usage)
901 //
902  xID->next = tabs.SYList;
903  tabs.SYList = xID;
904 
905 // All done
906 //
907  return 1;
908 }
909 
910 /******************************************************************************/
911 /* P r i v s C o n v e r t */
912 /******************************************************************************/
913 
914 int XrdAccConfig::PrivsConvert(char *privs, XrdAccPrivCaps &ctab)
915 {
916  int i = 0;
917  XrdAccPrivs ptab[] = {XrdAccPriv_None, XrdAccPriv_None}; // Speed conversion here
918 
919  // Convert the privs
920  //
921  while(*privs)
922  {switch((XrdAccPrivSpec)(*privs))
923  {case All_Priv:
924  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_All);
925  break;
926  case Delete_Priv:
927  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Delete);
928  break;
929  case Insert_Priv:
930  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Insert);
931  break;
932  case Lock_Priv:
933  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Lock);
934  break;
935  case Lookup_Priv:
936  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Lookup);
937  break;
938  case Rename_Priv:
939  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Rename);
940  break;
941  case Read_Priv:
942  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Read);
943  break;
944  case Write_Priv:
945  ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Write);
946  break;
947  case Neg_Priv: if (i) return 0; i++; break;
948  default: return 0;
949  }
950  privs++;
951  }
952  ctab.pprivs = ptab[0]; ctab.nprivs = ptab[1];
953  return 1;
954 }
XrdAccAudit_Options
Definition: XrdAccAudit.hh:37
@ audit_grant
Definition: XrdAccAudit.hh:39
@ audit_none
Definition: XrdAccAudit.hh:37
@ audit_deny
Definition: XrdAccAudit.hh:38
XrdAccAuthDB * XrdAccAuthDBObject(XrdSysError *erp)
#define ACC_PGO
Definition: XrdAccConfig.cc:75
#define TS_Bit(x, m, v)
Definition: XrdAccConfig.cc:73
void * XrdAccConfig_Refresh(void *start_data)
Definition: XrdAccConfig.cc:84
#define TS_Xeq(x, m)
Definition: XrdAccConfig.cc:67
XrdAccConfig XrdAccConfiguration
Definition: XrdAccConfig.cc:61
XrdAccGroupType
Definition: XrdAccGroups.hh:90
@ XrdAccNoGroup
Definition: XrdAccGroups.hh:90
@ XrdAccNetGroup
Definition: XrdAccGroups.hh:90
@ XrdAccUnixGroup
Definition: XrdAccGroups.hh:90
@ Primary_Only
Definition: XrdAccGroups.hh:81
XrdAccPrivSpec
Definition: XrdAccPrivs.hh:62
@ Delete_Priv
Definition: XrdAccPrivs.hh:63
@ Rename_Priv
Definition: XrdAccPrivs.hh:67
@ Read_Priv
Definition: XrdAccPrivs.hh:68
@ Neg_Priv
Definition: XrdAccPrivs.hh:70
@ Insert_Priv
Definition: XrdAccPrivs.hh:64
@ Lookup_Priv
Definition: XrdAccPrivs.hh:66
@ Write_Priv
Definition: XrdAccPrivs.hh:69
@ All_Priv
Definition: XrdAccPrivs.hh:62
@ Lock_Priv
Definition: XrdAccPrivs.hh:65
XrdAccPrivs
Definition: XrdAccPrivs.hh:39
@ XrdAccPriv_Insert
Definition: XrdAccPrivs.hh:44
@ XrdAccPriv_Lookup
Definition: XrdAccPrivs.hh:47
@ XrdAccPriv_Rename
Definition: XrdAccPrivs.hh:48
@ XrdAccPriv_All
Definition: XrdAccPrivs.hh:39
@ XrdAccPriv_Read
Definition: XrdAccPrivs.hh:49
@ XrdAccPriv_Lock
Definition: XrdAccPrivs.hh:45
@ XrdAccPriv_None
Definition: XrdAccPrivs.hh:53
@ XrdAccPriv_Write
Definition: XrdAccPrivs.hh:51
@ XrdAccPriv_Delete
Definition: XrdAccPrivs.hh:43
int open(const char *path, int oflag,...)
void SwapTabs(struct XrdAccAccess_Tables &newtab)
void setAudit(XrdAccAudit_Options aops)
Definition: XrdAccAudit.hh:90
virtual int Changed(const char *path=0)=0
virtual int Close()=0
virtual int getPP(char **path, char **priv, bool &istmplt)=0
virtual char getRec(char **recname)=0
virtual int Open(XrdSysError &eroute, const char *path=0)=0
virtual char getID(char **id)=0
void Add(XrdAccCapName *cnp)
XrdAccCapability * Find(const char *name)
XrdAccCapability * Next()
void Add(XrdAccCapability *newcap)
int Configure(XrdSysError &Eroute, const char *cfn)
XrdAccAccess * Authorization
Definition: XrdAccConfig.hh:78
int ConfigDB(int Warm, XrdSysError &Eroute)
XrdAccGroups GroupMaster
Definition: XrdAccConfig.hh:79
char * AddName(const XrdAccGroupType gtype, const char *name)
int Retran(const gid_t gid)
void SetOptions(XrdAccGroups_Options opts)
void SetLifetime(const int seconds)
void SetDomain(const char *dname)
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.icc:61
T * Find(const char *KeyVal, time_t *KeyTime=0)
Definition: XrdOucHash.icc:160
static int Decode(const char *src, int len, char *dst)
Definition: XrdOucUri.cc:116
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:45
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:288
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
Definition: XrdSysError.cc:141
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
XrdCmsConfig Config
XrdAccAccess_ID * Export()
Definition: XrdAccAccess.hh:62
XrdAccCapability * caps
Definition: XrdAccAccess.hh:54
XrdAccAccess_ID * next
Definition: XrdAccAccess.hh:55
XrdOucHash< XrdAccCapability > * U_Hash
Definition: XrdAccAccess.hh:93
XrdOucHash< XrdAccCapability > * G_Hash
Definition: XrdAccAccess.hh:86
XrdAccCapName * E_List
Definition: XrdAccAccess.hh:95
XrdOucHash< XrdAccCapability > * N_Hash
Definition: XrdAccAccess.hh:88
XrdAccCapability * X_List
Definition: XrdAccAccess.hh:96
XrdAccAccess_ID * SXList
Definition: XrdAccAccess.hh:98
XrdAccCapability * Z_List
Definition: XrdAccAccess.hh:97
XrdOucHash< XrdAccCapability > * T_Hash
Definition: XrdAccAccess.hh:92
XrdOucHash< XrdAccCapability > * O_Hash
Definition: XrdAccAccess.hh:89
XrdAccCapName * D_List
Definition: XrdAccAccess.hh:94
XrdOucHash< XrdAccCapability > * H_Hash
Definition: XrdAccAccess.hh:87
XrdOucHash< XrdAccAccess_ID > * S_Hash
Definition: XrdAccAccess.hh:91
XrdOucHash< XrdAccCapability > * R_Hash
Definition: XrdAccAccess.hh:90
XrdAccAccess_ID * SYList
Definition: XrdAccAccess.hh:99
XrdAccPrivs nprivs
Definition: XrdAccPrivs.hh:78
XrdAccPrivs pprivs
Definition: XrdAccPrivs.hh:77