[0001] [0002] [0003] [0004] [0005] [0006] [0007] [0008] [0009] [0010] [0011] [0012] [0013] [0014] [0015] [0016] [0017] [0018] [0019] [0020] [0021] [0022] [0023] [0024] [0025] [0026] [0027] [0028] [0029] [0030] [0031] [0032] [0033] [0034] [0035] [0036] [0037] [0038] [0039] [0040] [0041] [0042] [0043] [0044] [0045] [0046] [0047] [0048] [0049] [0050] [0051] [0052] [0053] [0054] [0055] [0056] [0057] [0058] [0059] [0060] [0061] [0062] [0063] [0064] [0065] [0066] [0067] [0068] [0069] [0070] [0071] [0072] [0073] [0074] [0075] [0076] [0077] [0078] [0079] [0080] [0081] [0082] [0083] [0084] [0085] [0086] [0087] [0088] [0089] [0090] [0091] [0092] [0093] [0094] [0095] [0096] [0097] [0098] [0099] [0100] [0101] [0102] [0103] [0104] [0105] [0106] [0107] [0108] [0109] [0110] [0111] [0112] [0113] [0114] [0115] [0116] [0117] [0118] [0119] [0120] [0121] [0122] [0123] [0124] [0125] [0126] [0127] [0128] [0129] [0130] [0131] [0132] [0133] [0134] [0135] [0136] [0137] [0138] [0139] [0140] [0141] [0142] [0143] [0144] [0145] [0146] [0147] [0148] [0149] [0150] [0151] [0152] [0153] [0154] [0155] [0156] [0157] [0158] [0159] [0160] [0161] [0162] [0163] [0164] [0165] [0166] [0167] [0168] [0169] [0170] [0171] [0172] [0173] [0174] [0175] [0176] [0177] [0178] [0179] [0180] [0181] [0182] [0183] [0184] [0185] [0186] [0187] [0188] [0189] [0190] [0191] [0192] [0193] [0194] [0195] [0196] [0197] [0198] [0199] [0200] [0201] [0202] [0203] [0204] [0205] [0206] [0207] [0208] [0209] [0210] [0211] [0212] [0213] [0214] [0215] [0216] [0217] [0218] [0219] [0220] [0221] [0222] [0223] [0224] [0225] [0226] [0227] [0228] [0229] [0230] [0231] [0232] [0233] [0234] [0235] [0236] [0237] [0238] [0239] [0240] [0241] [0242] [0243] [0244] [0245] [0246] [0247] [0248] [0249] [0250] [0251] [0252] [0253] [0254] [0255] [0256] [0257] [0258] [0259] [0260] [0261] [0262] [0263] [0264] [0265] [0266] [0267] [0268] [0269] [0270] [0271] [0272] [0273] [0274] [0275] [0276] [0277] [0278] [0279] [0280] [0281] [0282] [0283] [0284] [0285] [0286] [0287] [0288] [0289] [0290] [0291] [0292] [0293] [0294] [0295] [0296] [0297] [0298] [0299] [0300] [0301] [0302] [0303] [0304] [0305] [0306]
/*****************************************************************************/ /* AuthHTL.c THE GNU GENERAL PUBLIC LICENSE APPLIES DOUBLY TO ANYTHING TO DO WITH AUTHENTICATION AND AUTHORIZATION! This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License, or any later version. > This package is distributed in the hope that it will be useful, > but WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. This module provides functions related to the authentication of case-insensitive usernames via simple lists of names (and optional case-insensitive passwords and user detail). See AUTH.C for overall detail on the WASD authorization environment. VERSION HISTORY --------------- 26-JUN-2012 MGD bugfix; AuthReadSimpleList() parameter /DIRECTORY= processing 26-AUG-2003 MGD service directory located authorization databases 12-AUG-2003 MGD allow the database directory location to be specified using an authorization rule 'param="/directory=device:[directory]"' 27-APR-2002 MGD use sys$setprv() 04-AUG-2001 MGD support module WATCHing 05-FEB-2000 MGD change HTL database type from ".HTL" to ".$HTL" (keep the nomenclature in line with ".$HTA", see AUTHHTA.C) 01-JAN-2000 MGD no significant modifications for ODS-5 (no NAM block) 28-AUG-1999 MGD unbundled from AUTH.C for v6.1 */ /*****************************************************************************/ #ifdef WASD_VMS_V7 #undef _VMS__V6__SOURCE #define _VMS__V6__SOURCE #undef __VMS_VER #define __VMS_VER 70000000 #undef __CRTL_VER #define __CRTL_VER 70000000 #endif /* standard C header files */ #include <ctype.h> #include <errno.h> #include <stdio.h> #include <string.h> /* VMS related header files */ #include <descrip.h> #include <rms.h> #include <rmsdef.h> #include <ssdef.h> #include <stsdef.h> /* application related header files */ #include "wasd.h" #define WASD_MODULE "AUTHHTL" #if WATCH_MOD #define FI_NOLI WASD_MODULE, __LINE__ #else /* in production let's keep the exact line to ourselves! */ #define FI_NOLI WASD_MODULE, 0 #endif /********************/ /* external storage */ /********************/ extern int ToLowerCase[], ToUpperCase[]; extern unsigned long SysPrvMask[]; extern char *AuthConfigHtaDirectory; extern char ErrorSanityCheck[]; extern ACCOUNTING_STRUCT *AccountingPtr; extern MSG_STRUCT Msgs; extern WATCH_STRUCT Watch; /****************************************************************************/ /* */ int AuthReadSimpleList ( REQUEST_STRUCT* rqptr, char *DatabaseName, BOOL AuthenticatePassword ) { int status, AuthFileNameLength; char *cptr, *sptr, *zptr, *cptrBuffer; char AuthFileName [256], Line [1024]; struct FAB AuthFileFab; struct RAB AuthFileRab; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_AUTH)) WatchThis (WATCHITM(rqptr), WATCH_MOD_AUTH, "AuthReadSimpleList() !&Z !&Z !&B", DatabaseName, rqptr->RemoteUser, AuthenticatePassword); /* flag that case-less username and password checks were performed */ rqptr->rqAuth.CaseLess = true; /* must supply a user name and database name */ if (!rqptr->RemoteUser[0] || !DatabaseName[0]) return (AUTH_DENIED_BY_LOGIN); if (rqptr->rqAuth.PathParameterPtr && rqptr->rqAuth.PathParameterPtr[0]) { if ((cptr = strstr (rqptr->rqAuth.PathParameterPtr, "/directory=")) || (cptr = strstr (rqptr->rqAuth.PathParameterPtr, "/DIRECTORY="))) cptr += 11; else cptr = NULL; } else cptr = NULL; if (!cptr) { if (rqptr->rqAuth.DirectoryPtr) cptr = rqptr->rqAuth.DirectoryPtr; else if (rqptr->ConfigDirectory[0]) cptr = rqptr->ConfigDirectory; else cptr = AuthConfigHtaDirectory; } /* just a safeguard against the service directory not being configured */ if (!*cptr) cptr = AUTH_DIR_NOT_CONFIGURED; zptr = (sptr = AuthFileName) + sizeof(AuthFileName)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; for (cptr = DatabaseName; *cptr && sptr < zptr; *sptr++ = *cptr++); for (cptr = HTL_FILE_TYPE; *cptr && sptr < zptr; *sptr++ = *cptr++); *sptr = '\0'; AuthFileNameLength = sptr - AuthFileName; if (WATCHING (rqptr, WATCH_AUTH)) WatchThis (WATCHITM(rqptr), WATCH_AUTH, "FILE !AZ", AuthFileName); AuthFileFab = cc$rms_fab; AuthFileFab.fab$b_fac = FAB$M_GET; AuthFileFab.fab$l_fna = AuthFileName; AuthFileFab.fab$b_fns = AuthFileNameLength; AuthFileFab.fab$b_shr = FAB$M_SHRGET; /* turn on SYSPRV to allow access to authentication database file */ sys$setprv (1, &SysPrvMask, 0, 0); status = sys$open (&AuthFileFab, 0, 0); sys$setprv (0, &SysPrvMask, 0, 0); /* status from sys$open() */ if (VMSnok (status)) { rqptr->rqResponse.HttpStatus = 500; rqptr->rqResponse.ErrorTextPtr = MsgFor(rqptr,MSG_AUTH_DATABASE); rqptr->rqResponse.ErrorOtherTextPtr = DatabaseName; ErrorVmsStatus (rqptr, status, FI_LI); return (status); } AuthFileRab = cc$rms_rab; AuthFileRab.rab$l_fab = &AuthFileFab; AuthFileRab.rab$b_mbf = 2; AuthFileRab.rab$l_rop = RAB$M_RAH; if (VMSnok (status = sys$connect (&AuthFileRab, 0, 0))) { sys$close (&AuthFileFab, 0, 0); rqptr->rqResponse.HttpStatus = 500; rqptr->rqResponse.ErrorTextPtr = MsgFor(rqptr,MSG_AUTH_DATABASE); rqptr->rqResponse.ErrorOtherTextPtr = DatabaseName; ErrorVmsStatus (rqptr, status, FI_LI); return (status); } /*****************/ /* locate record */ /*****************/ AuthFileRab.rab$l_ubf = Line; AuthFileRab.rab$w_usz = sizeof(Line)-1; while (VMSok (status = sys$get (&AuthFileRab, 0, 0))) { AuthFileRab.rab$l_rbf[AuthFileRab.rab$w_rsz] = '\0'; if (AuthFileRab.rab$w_rsz) { if (AuthFileRab.rab$l_ubf[AuthFileRab.rab$w_rsz-1] == '\\') { /* directive is continued on next line */ AuthFileRab.rab$l_ubf[AuthFileRab.rab$w_rsz-1] = ' '; AuthFileRab.rab$l_ubf += AuthFileRab.rab$w_rsz; AuthFileRab.rab$w_usz -= AuthFileRab.rab$w_rsz; continue; } } for (cptr = Line; *cptr && ISLWS(*cptr); cptr++) if (*cptr == '#' || *cptr == '!') continue; sptr = rqptr->RemoteUser; while (*cptr && !ISLWS(*cptr) && *cptr != '=' && *sptr && TOLO(*cptr) == TOLO(*sptr)) { cptr++; sptr++; } if ((*cptr && !ISLWS(*cptr) && *cptr != '=') || *sptr) continue; break; } sys$close (&AuthFileFab); if (status == RMS$_EOF) { /* user record not found */ if (WATCHING (rqptr, WATCH_AUTH)) WatchThis (WATCHITM(rqptr), WATCH_AUTH, "FAIL !AZ!AZ username", DatabaseName, AuthSourceString (DatabaseName, AUTH_SOURCE_LIST)); if (AuthenticatePassword) return (AUTH_DENIED_BY_LOGIN); else return (AUTH_DENIED_BY_GROUP); } /* if just checking if the user name is an entry in the list file */ if (!AuthenticatePassword) return (SS$_NORMAL); sptr = cptr; if (*sptr == '=') while (*sptr && !ISLWS(*sptr)) sptr++; while (*sptr && ISLWS(*sptr)) sptr++; if (*sptr) { cptrBuffer = cptr; for (cptr = sptr; *cptr; cptr++); if (cptr > sptr) cptr--; while (cptr > sptr && ISLWS(*cptr)) cptr--; if (!ISLWS(*cptr)) cptr++; *cptr = '\0'; rqptr->rqAuth.UserDetailsLength = cptr - sptr; rqptr->rqAuth.UserDetailsPtr = cptr = VmGetHeap (rqptr, rqptr->rqAuth.UserDetailsLength+1); strcpy (cptr, sptr); cptr = cptrBuffer; } /* if just checking if the user name is an entry in the list file */ if (!AuthenticatePassword) return (status); /* simple, clear-text password comparison */ if (*cptr != '=') { if (WATCHING (rqptr, WATCH_AUTH)) WatchThis (WATCHITM(rqptr), WATCH_AUTH, "FAIL !AZ!AZ no password", DatabaseName, AuthSourceString (DatabaseName, AUTH_SOURCE_LIST)); return (AUTH_DENIED_BY_LOGIN); } while (*cptr && *cptr == '=') cptr++; sptr = rqptr->RemoteUserPassword; while (*cptr && !ISLWS(*cptr) && *sptr && TOLO(*cptr) == TOLO(*sptr)) { cptr++; sptr++; } if ((*cptr && !ISLWS(*cptr)) || *sptr) { /* passwords do not match */ if (WATCHING (rqptr, WATCH_AUTH)) WatchThis (WATCHITM(rqptr), WATCH_AUTH, "FAIL !AZ!AZ password", DatabaseName, AuthSourceString (DatabaseName, AUTH_SOURCE_LIST)); return (AUTH_DENIED_BY_LOGIN); } /* passwords match */ return (SS$_NORMAL); } /****************************************************************************/