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