XrdSecProtocolunix.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                 X r d S e c P r o t o c o l u n i x . c c                  */
00004 /*                                                                            */
00005 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 #include <unistd.h>
00012 #include <ctype.h>
00013 #include <errno.h>
00014 #include <stdlib.h>
00015 #include <strings.h>
00016 #include <grp.h>
00017 #include <pwd.h>
00018 #include <sys/types.h>
00019 
00020 #include "XrdOuc/XrdOucErrInfo.hh"
00021 #include "XrdSys/XrdSysHeaders.hh"
00022 #include "XrdSys/XrdSysPthread.hh"
00023 #include "XrdSec/XrdSecInterface.hh"
00024 
00025 /******************************************************************************/
00026 /*              X r d S e c P r o t o c o l u n i x   C l a s s               */
00027 /******************************************************************************/
00028 
00029 class XrdSecProtocolunix : public XrdSecProtocol
00030 {
00031 public:
00032 friend class XrdSecProtocolDummy; // Avoid stupid gcc warnings about destructor
00033 
00034 
00035         int                Authenticate  (XrdSecCredentials *cred,
00036                                           XrdSecParameters **parms,
00037                                           XrdOucErrInfo     *einfo=0);
00038 
00039         XrdSecCredentials *getCredentials(XrdSecParameters  *parm=0,
00040                                           XrdOucErrInfo     *einfo=0);
00041 
00042         XrdSecProtocolunix(const char                *hname,
00043                            const struct sockaddr     *ipadd)
00044                           : XrdSecProtocol("unix")
00045                           {Entity.host = strdup(hname);
00046                            Entity.name = (char *)"?";
00047                            credBuff    = 0;
00048                           }
00049 
00050         void              Delete() {delete this;}
00051 
00052 private:
00053 
00054        ~XrdSecProtocolunix() {if (credBuff)    free(credBuff);
00055                               if (Entity.host) free(Entity.host);
00056                              } // via Delete()
00057 
00058 struct sockaddr           hostaddr;      // Client-side only
00059 char                     *credBuff;      // Credentials buffer (server)
00060 };
00061 
00062 /******************************************************************************/
00063 /*             C l i e n t   O r i e n t e d   F u n c t i o n s              */
00064 /******************************************************************************/
00065 /******************************************************************************/
00066 /*                        g e t C r e d e n t i a l s                         */
00067 /******************************************************************************/
00068 
00069 
00070 XrdSecCredentials *XrdSecProtocolunix::getCredentials(XrdSecParameters *noparm,
00071                                                       XrdOucErrInfo    *error)
00072 {
00073    struct passwd *pEnt;
00074    struct group  *pGrp;
00075    char Buff[1024], *Bp;
00076    int Blen;
00077 
00078 // Set protocol ID in the buffer
00079 //
00080    strcpy(Buff, "unix"); Bp = Buff + 5;
00081 
00082 // Get the username
00083 //
00084    if (!(pEnt = getpwuid(geteuid()))) strcpy(Bp, "*");
00085       else strcpy(Bp, pEnt->pw_name);
00086    Bp += strlen(Bp);
00087 
00088 // Get the group name
00089 //
00090    if ((pGrp = getgrgid(getegid())))
00091       {*Bp++ = ' '; strcpy(Bp, pGrp->gr_name); Bp += strlen(Bp);}
00092 
00093 // Return the credentials
00094 //
00095    Blen = Bp-Buff+1;
00096    Bp = (char *)malloc(Blen);
00097    memcpy(Bp, Buff, Blen);
00098    return new XrdSecCredentials(Bp, Blen);
00099 }
00100 
00101 /******************************************************************************/
00102 /*               S e r v e r   O r i e n t e d   M e t h o d s                */
00103 /******************************************************************************/
00104 /******************************************************************************/
00105 /*                          A u t h e n t i c a t e                           */
00106 /******************************************************************************/
00107 
00108 int XrdSecProtocolunix::Authenticate(XrdSecCredentials *cred,
00109                                      XrdSecParameters **parms,
00110                                      XrdOucErrInfo     *erp)
00111 {
00112    char *bp, *ep;
00113 
00114 // Check if we have any credentials or if no credentials really needed.
00115 // In either case, use host name as client name
00116 //
00117    if (cred->size <= int(4) || !cred->buffer)
00118       {strncpy(Entity.prot, "host", sizeof(Entity.prot));
00119        Entity.name = (char *)"?";
00120        return 0;
00121       }
00122 
00123 // Check if this is our protocol
00124 //
00125    if (strcmp(cred->buffer, "unix"))
00126       {char msg[256];
00127        snprintf(msg, sizeof(msg),
00128                 "Secunix: Authentication protocol id mismatch (unix != %.4s).",
00129                 cred->buffer);
00130        if (erp) erp->setErrInfo(EINVAL, msg);
00131           else cerr <<msg <<endl;
00132        return -1;
00133       }
00134 
00135 // Skip over the protocol ID and copy the buffer
00136 //
00137    bp = credBuff = strdup((cred->buffer)+5);
00138    ep = bp + strlen(bp);
00139 
00140 // Extract out username
00141 //
00142    while(*bp && *bp == ' ') bp++;
00143    Entity.name = bp;
00144    while(*bp && *bp != ' ') bp++;
00145    *bp++ = '\0';
00146 
00147 // Extract out the group name
00148 //
00149    if (bp >= ep) return 0;
00150    while(*bp && *bp == ' ') bp++;
00151    Entity.grps = bp;
00152 
00153 // All done
00154 //
00155    return 0;
00156 }
00157   
00158 /******************************************************************************/
00159 /*                X r d S e c p r o t o c o l u n i x I n i t                 */
00160 /******************************************************************************/
00161   
00162 extern "C"
00163 {
00164 char  *XrdSecProtocolunixInit(const char     mode,
00165                               const char    *parms,
00166                               XrdOucErrInfo *erp)
00167 {
00168    return (char *)"";
00169 }
00170 }
00171 
00172 /******************************************************************************/
00173 /*              X r d S e c P r o t o c o l u n i x O b j e c t               */
00174 /******************************************************************************/
00175   
00176 extern "C"
00177 {
00178 XrdSecProtocol *XrdSecProtocolunixObject(const char              mode,
00179                                          const char             *hostname,
00180                                          const struct sockaddr  &netaddr,
00181                                          const char             *parms,
00182                                                XrdOucErrInfo    *erp)
00183 {
00184    XrdSecProtocolunix *prot;
00185 
00186 // Return a new protocol object
00187 //
00188    if (!(prot = new XrdSecProtocolunix(hostname, &netaddr)))
00189       {const char *msg = "Seckunix: Insufficient memory for protocol.";
00190        if (erp) erp->setErrInfo(ENOMEM, msg);
00191           else cerr <<msg <<endl;
00192        return (XrdSecProtocol *)0;
00193       }
00194 
00195 // All done
00196 //
00197    return prot;
00198 }
00199 }

Generated on Tue Jul 5 14:47:02 2011 for ROOT_528-00b_version by  doxygen 1.5.1