XRootD
XrdSecProtocolkrb5.cc File Reference
#include <unistd.h>
#include <cctype>
#include <cerrno>
#include <cstdlib>
#include <string>
#include <strings.h>
#include <cstdio>
#include <sys/param.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "krb5.h"
#include "com_err.h"
#include "XrdVersion.hh"
#include "XrdNet/XrdNetAddrInfo.hh"
#include "XrdNet/XrdNetUtils.hh"
#include "XrdOuc/XrdOucErrInfo.hh"
#include "XrdOuc/XrdOucEnv.hh"
#include "XrdSys/XrdSysHeaders.hh"
#include "XrdSys/XrdSysPthread.hh"
#include "XrdSys/XrdSysPwd.hh"
#include "XrdOuc/XrdOucTokenizer.hh"
#include "XrdSec/XrdSecInterface.hh"
+ Include dependency graph for XrdSecProtocolkrb5.cc:

Go to the source code of this file.

Classes

class  XrdSecProtocolkrb5
 

Macros

#define CLDBG(x)   if (client_options & XrdSecDEBUG) std::cerr <<"Seckrb5: " <<x <<std::endl;
 
#define CLPRT(x)   std::cerr <<"Seckrb5: " <<x <<std::endl;
 
#define krb_etxt(x)   (char *)error_message(x)
 
#define XrdSecDEBUG   0x1000
 
#define XrdSecEXPTKN   0x0002
 
#define XrdSecINITTKN   0x0004
 
#define XrdSecMAXPATHLEN   4096
 
#define XrdSecNOIPCHK   0x0001
 
#define XrdSecPROTOIDENT   "krb5"
 
#define XrdSecPROTOIDLEN   sizeof(XrdSecPROTOIDENT)
 

Typedefs

typedef krb5_error_code krb_rc
 

Functions

void __eprintf (const char *string, const char *expression, unsigned int line, const char *filename)
 
char * XrdSecProtocolkrb5Init (const char mode, const char *parms, XrdOucErrInfo *erp)
 
XrdSecProtocolXrdSecProtocolkrb5Object (const char mode, const char *hostname, XrdNetAddrInfo &endPoint, const char *parms, XrdOucErrInfo *erp)
 

Macro Definition Documentation

◆ CLDBG

#define CLDBG (   x)    if (client_options & XrdSecDEBUG) std::cerr <<"Seckrb5: " <<x <<std::endl;

Definition at line 82 of file XrdSecProtocolkrb5.cc.

◆ CLPRT

#define CLPRT (   x)    std::cerr <<"Seckrb5: " <<x <<std::endl;

Definition at line 83 of file XrdSecProtocolkrb5.cc.

◆ krb_etxt

#define krb_etxt (   x)    (char *)error_message(x)

Definition at line 71 of file XrdSecProtocolkrb5.cc.

◆ XrdSecDEBUG

#define XrdSecDEBUG   0x1000

Definition at line 78 of file XrdSecProtocolkrb5.cc.

◆ XrdSecEXPTKN

#define XrdSecEXPTKN   0x0002

Definition at line 76 of file XrdSecProtocolkrb5.cc.

◆ XrdSecINITTKN

#define XrdSecINITTKN   0x0004

Definition at line 77 of file XrdSecProtocolkrb5.cc.

◆ XrdSecMAXPATHLEN

#define XrdSecMAXPATHLEN   4096

Definition at line 80 of file XrdSecProtocolkrb5.cc.

◆ XrdSecNOIPCHK

#define XrdSecNOIPCHK   0x0001

Definition at line 75 of file XrdSecProtocolkrb5.cc.

◆ XrdSecPROTOIDENT

#define XrdSecPROTOIDENT   "krb5"

Definition at line 73 of file XrdSecProtocolkrb5.cc.

◆ XrdSecPROTOIDLEN

#define XrdSecPROTOIDLEN   sizeof(XrdSecPROTOIDENT)

Definition at line 74 of file XrdSecProtocolkrb5.cc.

Typedef Documentation

◆ krb_rc

typedef krb5_error_code krb_rc

Definition at line 85 of file XrdSecProtocolkrb5.cc.

Function Documentation

◆ __eprintf()

void __eprintf ( const char *  string,
const char *  expression,
unsigned int  line,
const char *  filename 
)

Definition at line 1069 of file XrdSecProtocolkrb5.cc.

1071  {
1072  fprintf (stderr, string, expression, line, filename);
1073  fflush (stderr);
1074  abort ();
1075  }
int fflush(FILE *stream)

References fflush().

+ Here is the call graph for this function:

◆ XrdSecProtocolkrb5Init()

char* XrdSecProtocolkrb5Init ( const char  mode,
const char *  parms,
XrdOucErrInfo erp 
)

Definition at line 902 of file XrdSecProtocolkrb5.cc.

905 {
906  char *op, *KPrincipal=0, *Keytab=0, *ExpFile=0;
907  char parmbuff[1024];
908  XrdOucTokenizer inParms(parmbuff);
909  int options = XrdSecNOIPCHK;
910  static bool serverinitialized = false;
911 
912 // For client-side one-time initialization, we only need to set debug flag and
913 // initialize the kerberos context and cache location.
914 //
915  if ((mode == 'c') || (serverinitialized))
916  {
917  int opts = 0;
918  if (getenv("XrdSecDEBUG")) opts |= XrdSecDEBUG;
919  if (getenv("XrdSecKRB5INITTKN")) opts |= XrdSecINITTKN;
921  return (XrdSecProtocolkrb5::Init(erp) ? (char *)0 : (char *)"");
922  }
923 
924  if (!serverinitialized) {
925  serverinitialized = true;
926  }
927 
928 // Duplicate the parms
929 //
930  if (parms) strlcpy(parmbuff, parms, sizeof(parmbuff));
931  else {char *msg = (char *)"Seckrb5: Kerberos parameters not specified.";
932  if (erp) erp->setErrInfo(EINVAL, msg);
933  else std::cerr <<msg <<std::endl;
934  return (char *)0;
935  }
936 
937 // Expected parameters: [<keytab>] [-ipchk] [-exptkn[:filetemplate]] <principal>
938 //
939  if (inParms.GetLine())
940  {if ((op = inParms.GetToken()) && *op == '/')
941  {Keytab = op; op = inParms.GetToken();}
942  if (op && !strcmp(op, "-ipchk"))
943  {options &= ~XrdSecNOIPCHK;
944  op = inParms.GetToken();
945  }
946  if (op && !strncmp(op, "-exptkn", 7))
947  {options |= XrdSecEXPTKN;
948  if (op[7] == ':') ExpFile = op+8;
949  op = inParms.GetToken();
950  }
951  KPrincipal = strdup(op);
952  }
953 
954  if (ExpFile)
955  fprintf(stderr,"Template for exports: %s\n", ExpFile);
956  else
957  fprintf(stderr,"Template for exports not set\n");
958 
959 // Now make sure that we have all the right info
960 //
961  if (!KPrincipal)
962  {char *msg = (char *)"Seckrb5: Kerberos principal not specified.";
963  if (erp) erp->setErrInfo(EINVAL, msg);
964  else std::cerr <<msg <<std::endl;
965  return (char *)0;
966  }
967 
968 // Expand possible keywords in the principal
969 //
970  int plen = strlen(KPrincipal);
971  int lkey = strlen("<host>");
972  char *phost = (char *) strstr(&KPrincipal[0], "<host>");
973  if (phost)
974  {char *hn = XrdNetUtils::MyHostName();
975  if (hn)
976  {int lhn = strlen(hn);
977  if (lhn != lkey) {
978  // Allocate, if needed
979  int lnew = plen - lkey + lhn;
980  if (lnew > plen) {
981  KPrincipal = (char *) realloc(KPrincipal, lnew+1);
982  KPrincipal[lnew] = 0;
983  phost = (char *) strstr(&KPrincipal[0], "<host>");
984  }
985  // Adjust the space
986  int lm = plen - (int)(phost + lkey - &KPrincipal[0]);
987  memmove(phost + lhn, phost + lkey, lm);
988  }
989  // Copy the name
990  memcpy(phost, hn, lhn);
991  // Cleanup
992  free(hn);
993  }
994  }
995 
996 // Now initialize the server
997 //
998  options |= XrdSecDEBUG;
1000  XrdSecProtocolkrb5::setOpts(options);
1001  if (!XrdSecProtocolkrb5::Init(erp, KPrincipal, Keytab))
1002  {free(KPrincipal);
1003  int lpars = strlen(XrdSecProtocolkrb5::getPrincipal());
1004  if (options & XrdSecEXPTKN)
1005  lpars += strlen(",fwd");
1006  char *params = (char *)malloc(lpars+1);
1007  if (params)
1008  {memset(params,0,lpars+1);
1009  strcpy(params,XrdSecProtocolkrb5::getPrincipal());
1010  if (options & XrdSecEXPTKN)
1011  strcat(params,",fwd");
1013  return params;
1014  }
1015  return (char *)0;
1016  }
1017 
1018 // Failure
1019 //
1020  free(KPrincipal);
1021  return (char *)0;
1022 }
#define XrdSecDEBUG
#define XrdSecEXPTKN
#define XrdSecINITTKN
#define XrdSecNOIPCHK
struct myOpts opts
size_t strlcpy(char *dst, const char *src, size_t sz)
static char * MyHostName(const char *eName="*unknown*", const char **eText=0)
Definition: XrdNetUtils.cc:667
int setErrInfo(int code, const char *emsg)
static void setOpts(int opts)
static void setClientOpts(int opts)
static char * getPrincipal()
static void setExpFile(char *expfile)
static void setParms(char *param)
static int Init(XrdOucErrInfo *einfo, char *KP=0, char *kfn=0)

References XrdOucTokenizer::GetLine(), XrdSecProtocolkrb5::getPrincipal(), XrdOucTokenizer::GetToken(), XrdSecProtocolkrb5::Init(), XrdNetUtils::MyHostName(), opts, XrdSecProtocolkrb5::setClientOpts(), XrdOucErrInfo::setErrInfo(), XrdSecProtocolkrb5::setExpFile(), XrdSecProtocolkrb5::setOpts(), XrdSecProtocolkrb5::setParms(), strlcpy(), XrdSecDEBUG, XrdSecEXPTKN, XrdSecINITTKN, and XrdSecNOIPCHK.

+ Here is the call graph for this function:

◆ XrdSecProtocolkrb5Object()

XrdSecProtocol* XrdSecProtocolkrb5Object ( const char  mode,
const char *  hostname,
XrdNetAddrInfo endPoint,
const char *  parms,
XrdOucErrInfo erp 
)

Definition at line 1031 of file XrdSecProtocolkrb5.cc.

1036 {
1037  XrdSecProtocolkrb5 *prot;
1038  char *KPrincipal=0;
1039 
1040 // If this is a client call, then we need to get the target principal from the
1041 // parms (which must be the first and only token). For servers, we use the
1042 // context we established at initialization time.
1043 //
1044  if (mode == 'c')
1045  {if ((KPrincipal = (char *)parms)) while(*KPrincipal == ' ') KPrincipal++;
1046  if (!KPrincipal || !*KPrincipal)
1047  {char *msg = (char *)"Seckrb5: Kerberos principal not specified.";
1048  if (erp) erp->setErrInfo(EINVAL, msg);
1049  else std::cerr <<msg <<std::endl;
1050  return (XrdSecProtocol *)0;
1051  }
1052  }
1053 
1054 // Get a new protocol object
1055 //
1056  if (!(prot = new XrdSecProtocolkrb5(KPrincipal, hostname, endPoint)))
1057  {char *msg = (char *)"Seckrb5: Insufficient memory for protocol.";
1058  if (erp) erp->setErrInfo(ENOMEM, msg);
1059  else std::cerr <<msg <<std::endl;
1060  return (XrdSecProtocol *)0;
1061  }
1062 
1063 // All done
1064 //
1065  return prot;
1066 }

References XrdOucErrInfo::setErrInfo().

+ Here is the call graph for this function: