diff --git a/zOS-RACF/Downloads/HFSUnload/HFSUnloadReadMe.pdf b/zOS-RACF/Downloads/HFSUnload/HFSUnloadReadMe.pdf new file mode 100644 index 00000000..d6915078 Binary files /dev/null and b/zOS-RACF/Downloads/HFSUnload/HFSUnloadReadMe.pdf differ diff --git a/zOS-RACF/Downloads/HFSUnload/RACHFSLD.txt b/zOS-RACF/Downloads/HFSUnload/RACHFSLD.txt new file mode 100644 index 00000000..a5b0863c --- /dev/null +++ b/zOS-RACF/Downloads/HFSUnload/RACHFSLD.txt @@ -0,0 +1,116 @@ +----------------------------------------------------------------------------- +-- Copyright 2022, IBM Corporation -- +-- -- +-- Licensed under the Apache License, Version 2.0 (the "License"); -- +-- you may not use this file except in compliance with the License. -- +-- You may obtain a copy of the License at -- +-- -- +-- http://www.apache.org/licenses/LICENSE-2.0 -- +-- -- +-- Unless required by applicable law or agreed to in writing, software -- +-- distributed under the License is distributed on an "AS IS" BASIS, -- +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.-- +-- See the License for the specific language governing permissions and -- +-- limitations under the License. -- +-- -- +LOAD DATA + INDDN IRRHFSU + RESUME YES + LOG NO + INTO TABLE USER01.HFS_BD + WHEN(1:4)='0900' ( + HFSBD_NAME POSITION(006:1028) CHAR(1023), + HFSBD_INODE POSITION(1030:1039) INTEGER EXTERNAL(10), + HFSBD_FILE_TYPE POSITION(1041:1048) CHAR(8), + HFSBD_OWN_UID POSITION(1050:1059) INTEGER EXTERNAL(10), + HFSBD_OWN_UNAME POSITION(1061:1068) CHAR(8), + HFSBD_OWN_GID POSITION(1070:1079) INTEGER EXTERNAL(10), + HFSBD_OWN_GNAME POSITION(1081:1088) CHAR(8), + HFSBD_S_ISUID POSITION(1090:1090) CHAR(1), + HFSBD_S_ISGID POSITION(1095:1095) CHAR(1), + HFSBD_S_ISVTX POSITION(1100:1100) CHAR(1), + HFSBD_OWN_READ POSITION(1105:1105) CHAR(1), + HFSBD_OWN_WRITE POSITION(1110:1110) CHAR(1), + HFSBD_OWN_EXEC POSITION(1115:1115) CHAR(1), + HFSBD_GRP_READ POSITION(1120:1120) CHAR(1), + HFSBD_GRP_WRITE POSITION(1125:1125) CHAR(1), + HFSBD_GRP_EXEC POSITION(1130:1130) CHAR(1), + HFSBD_OTH_READ POSITION(1135:1135) CHAR(1), + HFSBD_OTH_WRITE POSITION(1140:1140) CHAR(1), + HFSBD_OTH_EXEC POSITION(1145:1145) CHAR(1), + HFSBD_APF POSITION(1150:1150) CHAR(1), + HFSBD_PROGRAM POSITION(1155:1155) CHAR(1), + HFSBD_SHAREAS POSITION(1160:1160) CHAR(1), + HFSBD_AAUD_READ POSITION(1165:1172) CHAR(8), + HFSBD_AAUD_WRITE POSITION(1174:1181) CHAR(8), + HFSBD_AAUD_EXEC POSITION(1183:1190) CHAR(8), + HFSBD_UAUD_READ POSITION(1192:1199) CHAR(8), + HFSBD_UAUD_WRITE POSITION(1201:1208) CHAR(8), + HFSBD_UAUD_EXEC POSITION(1210:1217) CHAR(8), + HFSBD_AUDITID POSITION(1219:1250) CHAR(32), + HFSBD_FID POSITION(1252:1267) CHAR(16), + HFSBD_CREATE_DATE POSITION(1269:1278) DATE EXTERNAL(10), + HFSBD_CREATE_TIME POSITION(1280:1287) TIME EXTERNAL(8), + HFSBD_LASTREF_DATE POSITION(1289:1298) DATE EXTERNAL(10), + HFSBD_LASTREF_TIME POSITION(1300:1307) TIME EXTERNAL(8), + HFSBD_LASTCHG_DATE POSITION(1309:1318) DATE EXTERNAL(10), + HFSBD_LASTCHG_TIME POSITION(1320:1327) TIME EXTERNAL(8), + HFSBD_LASTDAT_DATE POSITION(1329:1338) DATE EXTERNAL(10), + HFSBD_LASTDAT_TIME POSITION(1340:1347) TIME EXTERNAL(8), + HFSBD_NUMBER_LINKS POSITION(1349:1358) INTEGER EXTERNAL(10), + HFSBD_SHARELIB POSITION(1360:1360) CHAR(1), + HFSBD_ACCESS_ACL POSITION(1365:1365) CHAR(1), + HFSBD_FILEMOD_ACL POSITION(1370:1370) CHAR(1), + HFSBD_DIRMOD_ACL POSITION(1375:1375) CHAR(1), + HFSBD_SECLABEL POSITION(1380:1387) CHAR(8), + HFSBD_DSNAME POSITION(1389:1432) CHAR(44), + HFSBD_LINK POSITION(1434:2456) CHAR(1023) + ) + + INTO TABLE USER01.HFS_AC + WHEN(1:4)='0901' ( + HFACC_NAME POSITION(006:1028) CHAR(1023), + HFACC_INODE POSITION(1030:1039) INTEGER EXTERNAL(10), + HFACC_TYPE POSITION(1041:1048) CHAR(8), + HFACC_UNIXID POSITION(1050:1059) INTEGER EXTERNAL(10), + HFACC_ID_NAME POSITION(1061:1068) CHAR(8), + HFACC_READ POSITION(1070:1070) CHAR(1), + HFACC_WRITE POSITION(1075:1075) CHAR(1), + HFACC_EXEC POSITION(1080:1080) CHAR(1) + ) + + INTO TABLE USER01.HFS_AF + WHEN(1:4)='0902' ( + HFACF_NAME POSITION(006:1028) CHAR(1023), + HFACF_INODE POSITION(1030:1039) INTEGER EXTERNAL(10), + HFACF_TYPE POSITION(1041:1048) CHAR(8), + HFACF_UNIXID POSITION(1050:1059) INTEGER EXTERNAL(10), + HFACF_ID_NAME POSITION(1061:1068) CHAR(8), + HFACF_READ POSITION(1070:1070) CHAR(1), + HFACF_WRITE POSITION(1075:1075) CHAR(1), + HFACF_EXEC POSITION(1080:1080) CHAR(1) + ) + + INTO TABLE USER01.HFS_AD + WHEN(1:4)='0903' ( + HFACD_NAME POSITION(006:1028) CHAR(1023), + HFACD_INODE POSITION(1030:1039) INTEGER EXTERNAL(10), + HFACD_TYPE POSITION(1041:1048) CHAR(8), + HFACD_UNIXID POSITION(1050:1059) INTEGER EXTERNAL(10), + HFACD_ID_NAME POSITION(1061:1068) CHAR(8), + HFACD_READ POSITION(1070:1070) CHAR(1), + HFACD_WRITE POSITION(1075:1075) CHAR(1), + HFACD_EXEC POSITION(1080:1080) CHAR(1) + ) + + INTO TABLE USER01.HFS_FS + WHEN(1:4)='0904' ( + HFMFS_DSNAME POSITION(006:049) CHAR(64), + HFMFS_TYPE POSITION(051:058) CHAR(8), + HFMFS_MODE POSITION(060:069) CHAR(10), + HFMFS_SECURITY POSITION(071:080) CHAR(10), + HFMFS_SETUID POSITION(082:091) CHAR(10), + HFMFS_MUID POSITION(093:102) INTEGER EXTERNAL(10), + HFMFS_MUSER POSITION(104:111) CHAR(8), + HFMFS_MOUNTPOINT POSITION(0113:1135) CHAR(1023) + ) diff --git a/zOS-RACF/Downloads/HFSUnload/RACHFSTB.txt b/zOS-RACF/Downloads/HFSUnload/RACHFSTB.txt new file mode 100644 index 00000000..c79f7d51 --- /dev/null +++ b/zOS-RACF/Downloads/HFSUnload/RACHFSTB.txt @@ -0,0 +1,259 @@ +----------------------------------------------------------------------------- +-- Copyright 2022, IBM Corporation -- +-- -- +-- Licensed under the Apache License, Version 2.0 (the "License"); -- +-- you may not use this file except in compliance with the License. -- +-- You may obtain a copy of the License at -- +-- -- +-- http://www.apache.org/licenses/LICENSE-2.0 -- +-- -- +-- Unless required by applicable law or agreed to in writing, software -- +-- distributed under the License is distributed on an "AS IS" BASIS, -- +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.-- +-- See the License for the specific language governing permissions and -- +-- limitations under the License. -- +-- -- +------------------------------------------------------------------------ +-- Create the TABLESPACE for the IRRHFSU tables -- +------------------------------------------------------------------------ +-- ; + CREATE TABLESPACE IRRHFSU IN RACFDB2 + LOCKSIZE TABLESPACE + SEGSIZE 64 + PCTFREE 0 + USING STOGROUP STOGRP01 + PRIQTY 2000 + SECQTY 500 + ERASE YES + ; +------------------------------------------------------------------------ +-- HFS Basic Data -- +------------------------------------------------------------------------ +-- ; +CREATE TABLE USER01.HFS_BD ( + HFSBD_NAME VARCHAR(1023) NOT NULL, + HFSBD_INODE INTEGER NOT NULL, + HFSBD_FILE_TYPE CHAR(8) NOT NULL, + HFSBD_OWN_UID INTEGER NOT NULL, + HFSBD_OWN_UNAME CHAR(8), + HFSBD_OWN_GID INTEGER NOT NULL, + HFSBD_OWN_GNAME CHAR(8), + HFSBD_S_ISUID CHAR(1) NOT NULL, + HFSBD_S_ISGID CHAR(1) NOT NULL, + HFSBD_S_ISVTX CHAR(1) NOT NULL, + HFSBD_OWN_READ CHAR(1) NOT NULL, + HFSBD_OWN_WRITE CHAR(1) NOT NULL, + HFSBD_OWN_EXEC CHAR(1) NOT NULL, + HFSBD_GRP_READ CHAR(1) NOT NULL, + HFSBD_GRP_WRITE CHAR(1) NOT NULL, + HFSBD_GRP_EXEC CHAR(1) NOT NULL, + HFSBD_OTH_READ CHAR(1) NOT NULL, + HFSBD_OTH_WRITE CHAR(1) NOT NULL, + HFSBD_OTH_EXEC CHAR(1) NOT NULL, + HFSBD_APF CHAR(1) NOT NULL, + HFSBD_PROGRAM CHAR(1) NOT NULL, + HFSBD_SHAREAS CHAR(1) NOT NULL, + HFSBD_AAUD_READ CHAR(8) NOT NULL, + HFSBD_AAUD_WRITE CHAR(8) NOT NULL, + HFSBD_AAUD_EXEC CHAR(8) NOT NULL, + HFSBD_UAUD_READ CHAR(8) NOT NULL, + HFSBD_UAUD_WRITE CHAR(8) NOT NULL, + HFSBD_UAUD_EXEC CHAR(8) NOT NULL, + HFSBD_AUDITID CHAR(32) NOT NULL, + HFSBD_FID CHAR(16) NOT NULL, + HFSBD_CREATE_DATE DATE NOT NULL, + HFSBD_CREATE_TIME TIME NOT NULL, + HFSBD_LASTREF_DATE DATE NOT NULL, + HFSBD_LASTREF_TIME TIME NOT NULL, + HFSBD_LASTCHG_DATE DATE NOT NULL, + HFSBD_LASTCHG_TIME TIME NOT NULL, + HFSBD_LASTDAT_DATE DATE NOT NULL, + HFSBD_LASTDAT_TIME TIME NOT NULL, + HFSBD_NUMBER_LINKS INTEGER NOT NULL, + HFSBD_SHARELIB CHAR(1) NOT NULL, + HFSBD_ACCESS_ACL CHAR(1) NOT NULL, + HFSBD_FILEMOD_ACL CHAR(1) NOT NULL, + HFSBD_DIRMOD_ACL CHAR(1) NOT NULL, + HFSBD_SECLABEL CHAR(8), + HFSBD_DSNAME CHAR(44), + HFSBD_LINK VARCHAR(1023) + ) + IN RACFDB2.IRRHFSU + ; + +------------------------------------------------------------------------ +-- HFS File Access record -- +------------------------------------------------------------------------ +-- ; +CREATE TABLE USER01.HFS_AC ( + HFACC_NAME VARCHAR(1023) NOT NULL, + HFACC_INODE INTEGER NOT NULL, + HFACC_TYPE CHAR(8) NOT NULL, + HFACC_UNIXID INTEGER NOT NULL, + HFACC_ID_NAME CHAR(8), + HFACC_READ CHAR(1) NOT NULL, + HFACC_WRITE CHAR(1) NOT NULL, + HFACC_EXEC CHAR(1) NOT NULL + ) + IN RACFDB2.IRRHFSU + ; + +------------------------------------------------------------------------ +-- HFS File Model Access record -- +------------------------------------------------------------------------ +-- ; +CREATE TABLE USER01.HFS_AF ( + HFACF_NAME VARCHAR(1023) NOT NULL, + HFACF_INODE INTEGER NOT NULL, + HFACF_TYPE CHAR(8) NOT NULL, + HFACF_UNIXID INTEGER NOT NULL, + HFACF_ID_NAME CHAR(8), + HFACF_READ CHAR(1) NOT NULL, + HFACF_WRITE CHAR(1) NOT NULL, + HFACF_EXEC CHAR(1) NOT NULL + ) + IN RACFDB2.IRRHFSU + ; + + +------------------------------------------------------------------------ +-- HFS Directory Model Access record -- +------------------------------------------------------------------------ +-- ; +CREATE TABLE USER01.HFS_AD ( + HFACD_NAME VARCHAR(1023) NOT NULL, + HFACD_INODE INTEGER NOT NULL, + HFACD_TYPE CHAR(8) NOT NULL, + HFACD_UNIXID INTEGER NOT NULL, + HFACD_ID_NAME CHAR(8), + HFACD_READ CHAR(1) NOT NULL, + HFACD_WRITE CHAR(1) NOT NULL, + HFACD_EXEC CHAR(1) NOT NULL + ) + IN RACFDB2.IRRHFSU + ; + + +------------------------------------------------------------------------ +-- HFS Mounted File System record -- +------------------------------------------------------------------------ +-- ; +CREATE TABLE USER01.HFS_FS ( + HFMFS_DSNAME CHAR(64) NOT NULL, + HFMFS_TYPE CHAR(8) NOT NULL, + HFMFS_MODE CHAR(10) NOT NULL, + HFMFS_SECURITY CHAR(10) NOT NULL, + HFMFS_SETUID CHAR(10) NOT NULL, + HFMFS_MUID INTEGER NOT NULL, + HFMFS_MUSER CHAR(8) NOT NULL, + HFMFS_MOUNTPOINT VARCHAR(1023) + ) + IN RACFDB2.IRRHFSU + ; + + + +------------------------------------------------------------------------ +-- Indices for the HFS Basic Data Record Type (0900) -- +------------------------------------------------------------------------ +-- ; +CREATE INDEX USER01.HFS_BD_IX1 + ON USER01.HFS_BD + (HFSBD_OWN_UID) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + CLUSTER + PCTFREE 0 + CLOSE NO + ; +CREATE INDEX USER01.HFS_BD_IX2 + ON USER01.HFS_BD + (HFSBD_OWN_UNAME) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; +CREATE INDEX USER01.HFS_BD_IX3 + ON USER01.HFS_BD + (HFSBD_OWN_GID) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; +CREATE INDEX USER01.HFS_BD_IX4 + ON USER01.HFS_BD + (HFSBD_OWN_GNAME) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; + +CREATE INDEX USER01.HFS_AC_IX1 + ON USER01.HFS_AC + (HFACC_UNIXID) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; + +CREATE INDEX USER01.HFS_AC_IX2 + ON USER01.HFS_AC + (HFACC_ID_NAME) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; +CREATE INDEX USER01.HFS_AF_IX1 + ON USER01.HFS_AF + (HFACF_UNIXID) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; + + +CREATE INDEX USER01.HFS_AF_IX2 + ON USER01.HFS_AF + (HFACF_ID_NAME) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; + + +CREATE INDEX USER01.HFS_AD_IX1 + ON USER01.HFS_AD + (HFACD_UNIXID) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; + + +CREATE INDEX USER01.HFS_AD_IX2 + ON USER01.HFS_AD + (HFACD_ID_NAME) + USING STOGROUP STOGRP01 + PRIQTY 100 + SECQTY 50 + PCTFREE 0 + CLOSE NO + ; + diff --git a/zOS-RACF/Downloads/HFSUnload/irrhfsu.o b/zOS-RACF/Downloads/HFSUnload/irrhfsu.o new file mode 100644 index 00000000..efdbee30 Binary files /dev/null and b/zOS-RACF/Downloads/HFSUnload/irrhfsu.o differ diff --git a/zOS-RACF/Downloads/HFSUnload/irrhfsu.txt b/zOS-RACF/Downloads/HFSUnload/irrhfsu.txt new file mode 100644 index 00000000..50121826 --- /dev/null +++ b/zOS-RACF/Downloads/HFSUnload/irrhfsu.txt @@ -0,0 +1,1090 @@ +/********************************************************************** + * Copyright 2022, IBM Corporation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ +/**********************************************************************/ +/* hfsu : C program which unloads the security data of HFS files in */ +/* a manner compatible with that of the IRRDBU00 utility. */ +/* */ +/* Author: Bruce Wells brwells@us.ibm.com */ +/* */ +/* This program contains code made available by IBM Corporation on */ +/* an AS IS basis. Any one receiving these programs is considered to */ +/* be licensed under IBM copyrights to use the IBM-provided source */ +/* code in any way he or she deems fit, including copying it, */ +/* compiling it, modifying it, and redistributing it, with or without */ +/* modifications, except that it may be neither sold nor incorporated */ +/* within a product that is sold. No license under any IBM patents */ +/* or patent applications is to be implied from this copyright */ +/* license. */ +/* */ +/* The software is provided "as-is", and IBM disclaims all warranties,*/ +/* express or implied, including but not limited to implied warranties*/ +/* of merchantibility or fitness for a particular purpose. IBM shall */ +/* not be liable for any direct, indirect, incidental, special or */ +/* consequential damages arising out of this agreement or the use or */ +/* operation of the software. */ +/* */ +/* A user of this program should understand that IBM cannot provide */ +/* technical support for the program and will not be responsible for */ +/* any consequences of use of the program. */ +/* */ +/* NOTE: Some variant characters were replaced by their trigraph */ +/* representation in order to avoid problems using codepage */ +/* 1047 in various countries. */ +/* */ +/* The is replaced by */ +/* --- -------------- */ +/* left bracket ??( */ +/* right bracket ??) */ +/* vertical bar ??! */ +/* */ +/* Return values: */ +/* 0 - Successful completion */ +/* 1 - ftw() error */ +/* 2 - w_getmntent() error */ +/* 3 - Unable to obtain mount table storage */ +/* 5 - File I/O error */ +/* */ +/* Note: When using BPXBATCH, it multiplies the return value */ +/* by 256. */ +/* */ +/* Change Activity: */ +/* */ +/* $L0=HFSU HRF2608 000301 PDBRW1: Original Code @L0A*/ +/* $L1=HFSACL HRF7706 010615 PDSN1: ACL support @L1A*/ +/* $P1=Defect1 HRF7706 020529 PDBRW1: ACL fix @P1A*/ +/* $L2=MLS HRF7708 020605 PDBRW1: MultiLevel Security @L2A*/ +/* $L3=Filesys HRF7780 121017 PDBRW1: Show file system container @L3A*/ +/* $L4=Links HRF7780 121017 PDBRW1: Show contents of links @L4A*/ +/* $P2=Defect2 HRF7780 121105 PDBRW1: Propagate bad RC to exit @P2A*/ +/* $L5=FsAttrs HRF7780 121119 PDBRW1: Show file system attrs @L5A*/ +/* $P3=Defect3 HRF7780 130712 PDBRW1: Fix conditional compile @P3A*/ +/* $P4=Defect4 HRF7780 130730 PDBRW1: Change 0904 logic @P4A*/ +/* */ +/* Change Description: */ +/* */ +/* A000000-999999 Original Code */ +/* A - Updated by Shozab Naqvi to support the shared library @L1A*/ +/* extended attribute, and Access Control Lists (ACLs). @L1A*/ +/* C - Wrap conditional logic around include of acl.h @P1A*/ +/* - Put defaults into fields which can currently be null @P1A*/ +/* - Use trigraph representations of some variant characters @P1A*/ +/* to minimize codepage problems @P1A*/ +/* A - Unload the SECLABEL (security label) field @L2A*/ +/* A - Show data set containing the file system containing each @L3A*/ +/* object @L3A*/ +/* A - Show contents of symlinks and external links @L4A*/ +/* - Remove obsolete conditional compiler directives @L4A*/ +/* C - File error is not being propagated all the way out @P2A*/ +/* A - Add support to unload mount table information @L5A*/ +/* A - Allow code to be compiled on an R12 system @P3A*/ +/* A - Instead of first calculating how many file systems there @P4A*/ +/* are, and then retrieving them, structure the logic more @P4A*/ +/* like the documented samples by iteratively passing in a @P4A*/ +/* fixed size buffer. This seems to fix a reported problem @P4A*/ +/* where not all mounted file systems were being returned. @P4A*/ +/* */ +/**********************************************************************/ + +#define _XOPEN_SOURCE +#define _OPEN_SYS +#define _POSIX_SOURCE +#include +#include +#include +#include +#include +/*#include /*@L5A*/ +#define __UU +#include +#include +#include +#include + +int traverse (const char *file); +int unload (const char *file, const struct stat *st, int type); +char* mapit(const char idtype, int idvalue); + +int FS_Info(); /* Unload mount table information @L5A*/ + +int ACL_Info(const char *file,acl_type_t type_d,const struct stat *st, + int aclType); +static lacl_t Get_acl (const char *file,acl_type_t type_d,int *ret_num); + +FILE *stream; +int cleanup=0,entry_delete_counter=0; /* entry_delete_counter keeps + track of the deleted ACL + entries */ +int mountinfo=0; /* Don't include mount table info. + 1 = add mount info to output + 2 = output contains *only* + mount info @L5A*/ +/**********************************************************************/ +/* Declarations associated with the mount table entry @L3A*/ +/**********************************************************************/ +struct { /* Contains single mount entry */ + MNTE3H header; + W_MNTENT3 mount_table??(1??); +} work_area; /*@L3A*/ + +dev_t devnum=0; /* Device number of current file + system @L3A*/ +char fsname??(45??)="not specified"; /* Current file system data set + name @L3A*/ + +/**********************************************************************/ +/* Declarations associated with the uid/user and gid/group caches */ +/**********************************************************************/ +const int maxcache = 10; /* max no. of cache elements */ +struct cachelem { /* structure of a cache element */ + struct cachelem *prev; /* ptr to previous element */ + struct cachelem *next; /* ptr to next element */ + int id; /* uid or gid value */ + char name??(9??); /* associated user ID or group name + @P1C*/ +}; +struct cachelem *uidcache = 0; /* ptr to head of uid cache */ +struct cachelem *gidcache = 0; /* ptr to head of gid cache */ +int uidcount,gidcount; /* no. elements in uid,gid cache */ + +char *outvalue = NULL; +const char usertype = 'U'; +const char grouptype = 'G'; + + + +/**********************************************************************/ +/* main: */ +/* Read the input arguments and see if -c for cleanup is */ +/* specified. If so, set cleanup = 1. Cleanup removes ACL */ +/* references that can't be mapped to a user or group. */ +/* */ +/* Read the input arguments and see if -f filename was */ +/* specified. If so, see if it refers to an MVS data set. */ +/* If so, insert quotes into the path name. Open the output */ +/* file, if specified. Else use stdout. Then, invoke the */ +/* tree traversal routine for each specified file/directory. */ +/* */ +/* When done, free storage associated with the uid/gid cache */ +/* mechanisms. */ +/**********************************************************************/ +int +main(int argc, register char **argv) +{ + int ret,ret2; + int FS_rc = 0; /* rc from FS_Info routine @L5A*/ + int myargc = --argc; /* Subtract one for program name @L5A*/ + char outfile??(50??); /*@P1C*/ + struct cachelem *tempptr; + struct cachelem *nextptr; + struct stat* info; + FILE *fd; + + uidcount =0; + gidcount =0; + stream = stdout; + ++argv; + if (myargc > 0) { /*@L5C*/ + if (strcmp(*argv,"-c")==0) { + ++argv; + --myargc; /*@L5C*/ + cleanup=1; + } + if ((myargc > 0) && + (strcmp(*argv,"-m")==0)) { + ++argv; + --myargc; /*@L5C*/ + mountinfo=1; /* Add mount table info to output @L5A*/ + } + if ((myargc > 0) && + (strcmp(*argv,"-M")==0)) { + ++argv; + --myargc; /*@L5C*/ + mountinfo=2; /* Mount table is the only output @L5A*/ + } + if ((myargc > 0) && + (strcmp(*argv,"-f")==0)) + { + ++argv; + --myargc; /*@L5C*/ + if (strncmp("//",*argv,2)==0) + { + strcpy(outfile,"//"); + strcat(outfile,"'"); + strcat(outfile,&(argv??(0??)??(2??))); /*@P1C*/ + strcat(outfile,"'"); + } + else strcpy(outfile,*argv); + + stream = fopen(outfile,"a,lrecl=4096,recfm=vb"); + ++argv; + --myargc; /*@L5C*/ + } + } + + if (stream == 0) { + perror("IRR67700I fopen() error on output file\n"); + exit(2); + } + + /* Allocate storage for uid/gid name string */ + outvalue = (char *)malloc(9); + + /*******************************************************************/ + /* Initialize the mount table header. This single-entry table */ + /* will be used to obtain an individual mount entry when a */ + /* mount point is crossed. @L3A*/ + /*******************************************************************/ + memset(&work_area, 0x00, sizeof(work_area)); /*@L3A*/ + /* 'header' initialization to specify MNTE3 mapping format @L3A*/ + memcpy(work_area.header.mnt3H_cbid, MNTE3H_ID, 4); /*@L3A*/ + work_area.header.mnt3H_cblen = sizeof(struct mnte3); /*@L3A*/ + work_area.header.mnt3H_bodylen = sizeof(struct w_mntent3); /*@L3A*/ + + /*******************************************************************/ + /* If mount table information is desired, go create 0904 records */ + /* for all mounted file systems. @L5A*/ + /*******************************************************************/ + if (mountinfo > 0) { + FS_rc = FS_Info(); + if ((mountinfo == 2) && (FS_rc > 0)) { + ret2 = fclose(stream); + return FS_rc; + } + } + + /*******************************************************************/ + /* If we are not being asked for mount table information */ + /* exclusively, then go process input path names as usual. @L5A*/ + /*******************************************************************/ + if (mountinfo != 2) { /*@L5A*/ + for (; *argv != NULL; ++argv) + ret ??!= traverse(*argv); /*@P1C*/ + } /*@L5A*/ + + ret2 = fclose(stream); + + /* Release storage for uid/gid name string */ + free(outvalue); + + /* Release uid cache storage */ + for (tempptr = uidcache ; uidcount ; tempptr = nextptr) + { + nextptr = tempptr->next; + free(tempptr); + --uidcount; + } + + /* Release gid cache storage */ + for (tempptr = gidcache ; gidcount ; tempptr = nextptr) + { + nextptr = tempptr->next; + free(tempptr); + --gidcount; + } + + /* Print out a message indicating how many ACL entries were */ + /* deleted as a result of specifying the -c option. We will write */ + /* this message to the terminal, but if there is an error opening */ + /* the terminal (for example, if we are invoked by BPXBATCH), */ + /* then we will write the message to stderr instead. */ + if (cleanup==1) { + fd = fopen("/dev/tty","w"); + if (!fd) { + fprintf(stderr,"IRR67707I error opening /dev/tty\n"); + fprintf(stderr,"IRR67708I There were %d extended ACL entries" \ + " deleted as a result of specifying the" \ + " -c option.\n",entry_delete_counter); + } + else { + fprintf(fd,"IRR67708I There were %d extended ACL entries" \ + " deleted as a result of specifying the" \ + " -c option.\n",entry_delete_counter); + fclose(fd); + } + } + return (ret); +} + +/**********************************************************************/ +/* traverse: */ +/* Use the C library function ftw() to invoke the unload routine */ +/* for every object in the subtree specified by the input file. */ +/* The input can be a single file, in which case its contents */ +/* are unloaded. */ +/**********************************************************************/ +int +traverse(const char *file) +{ + int ftw_rc = 0; /*@P2A*/ + + ftw_rc = ftw(file, unload, 10); /*@P2A*/ + if (ftw_rc < 0) /*@P2C*/ + { + perror("IRR67701I ftw() error\n"); + return (1); + } + return (ftw_rc); /*@P2C*/ +} + +/**********************************************************************/ +/* unload: */ +/* Unload the security contents of the file into the output file. */ +/* The data is taken from the stat structure passed in by ftw. */ +/* In addition, UIDs are mapped into RACF user IDs and GIDs are */ +/* mapped into RACF group names. */ +/* */ +/* Checks for the existence of access, file default and directory */ +/* default ACLs. For each ACL that exists a call to ACL_Info is */ +/* made to unload that ACL. */ +/**********************************************************************/ +int +unload(const char *file, const struct stat *st, int type) +{ + char *tempval; + char *filetype; + struct tm *timeptr; + int i,ch; + char dest??(11??); /*@P1C*/ + int p_ret; + + switch (type) + { + case FTW_NS: + fprintf(stderr,"IRR67702I stat() could not be executed" \ + " on %s. Possible search error on parent" \ + " directory.\n",file); + break; + + case FTW_DNR: + fprintf(stderr,"IRR67703I Unable to read directory %s\n",file); + break; + + case FTW_D: + case FTW_F: + case FTW_SL: + /*********************************************************/ + /* If the file system device number is different from */ + /* the previous object's, then we have crossed a */ + /* mount point into a different file system. */ + /* Obtain its information via w_getmntent() so we can */ + /* output the correct file system data set name. The */ + /* current devno and fsname are saved globally so we */ + /* can reuse them when nothing has changed. @L5M*/ + /*********************************************************/ + if (st->st_dev != devnum) { /* If devno has changed */ + /* Save new value as current value. */ + devnum = st->st_dev; /*@L5M*/ + /* Set devno in mount table header to request only */ + /* this entry from w_getmntent(). */ + work_area.header.mh3_devno = devnum; /*@L5M*/ + if (w_getmntent((char *) &work_area, + sizeof(work_area)) == -1) { + perror("IRR67709I w_getmntent() error\n"); /*@L5M*/ + devnum = 0; /* Reset devnum so we try again @L5M*/ + } + else { + memcpy(fsname, + work_area.mount_table??(0??).mnt3_fsname, + sizeof(fsname)); /* Save new fsname @L5M*/ + } + } + + /* HFSBD_RECORD_TYPE - Type of this "IRRDBU00" record */ + /* */ + /* For each file, we will check the fprintf return code */ + /* once to see if we're still ok. If not, exit. For */ + /* example, if the output file runs out of space, this */ + /* program would chug merrily on unless we detect this */ + /* and stop. Theoretically, any of the following fprintf*/ + /* statements could fail, and with buffering, it is hard */ + /* to predict, so we will just check once for every file.*/ + p_ret = fprintf(stream,"0900"); + if (p_ret < 0) + { + perror("IRR67704I fprintf() error while writing to" \ + " output file\n"); + return (5); /* Arbitary number... */ + } + /* HFSBD_NAME - path name of file being unloaded */ + fprintf(stream," %-1023.1023s",file); + /* HFSBD_INODE - inode (file serial number) */ + fprintf(stream," %010u",st->st_ino); + /* HFSBD_FILE_TYPE - type of file */ + if (S_ISREG(st->st_mode)) + filetype="FILE "; + else if (S_ISDIR(st->st_mode)) + filetype="DIR "; + else if (S_ISSOCK(st->st_mode)) + filetype="SOCKET "; + else if (S_ISEXTL(st->st_mode,st->st_genvalue)) + filetype="EXTLINK "; + else if (S_ISLNK(st->st_mode)) + filetype="SYMLINK "; + else if (S_ISFIFO(st->st_mode)) + filetype="FIFO "; + else if (S_ISBLK(st->st_mode)) + filetype="BLOCK "; + else if (S_ISCHR(st->st_mode)) + filetype="CHAR "; + else + filetype="????????"; /*@P1C*/ + fprintf(stream," %s",filetype); + + + /* HFSBD_FILE_OWN_UID - owning UID */ + fprintf(stream," %010u",st->st_uid); + /* HFSBD_FILE_OWN_UNAM - corresponding RACF user ID */ + fprintf(stream," %-8s",mapit(usertype,st->st_uid)); + /* HFSBD_FILE_OWN_GID - owning GID */ + fprintf(stream," %010u",st->st_gid); + /* HFSBD_FILE_OWN_GNAM - corresponding RACF group name */ + fprintf(stream," %-8s",mapit(grouptype,st->st_gid)); + + /* HFSBD_S_ISUID - set-uid bit */ + (st->st_mode & S_ISUID)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_S_ISGID - set-gid bit */ + (st->st_mode & S_ISGID)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_S_ISVTX - sticky bit */ + (st->st_mode & S_ISVTX)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_OWN_READ - owner read permission bit */ + (st->st_mode & S_IRUSR)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_OWN_WRITE - owner write permission bit */ + (st->st_mode & S_IWUSR)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_OWN_EXEC - owner search/execute permission bit */ + (st->st_mode & S_IXUSR)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_GRP_READ - group read permission bit */ + (st->st_mode & S_IRGRP)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_GRP_WRITE - group write permission bi t */ + (st->st_mode & S_IWGRP)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_GRP_EXEC - group search/execute permission bit */ + (st->st_mode & S_IXGRP)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_OTH_READ - other read permission bit */ + (st->st_mode & S_IROTH)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_OTH_WRITE - other write permission bit */ + (st->st_mode & S_IWOTH)? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_OTH_EXEC - other search/execute permission bit */ + (st->st_mode & S_IXOTH)? + fprintf(stream," YES "): fprintf(stream," NO "); + + /* HFSBD_APF - APF authorization setting */ + (S_ISAPF_AUTH(st->st_mode,st->st_genvalue))? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_PROGRAM - program control setting */ + (S_ISPROG_CTL(st->st_mode,st->st_genvalue))? + fprintf(stream," YES "): fprintf(stream," NO "); + /* HFSBD_SHAREAS - runs in shared address space setting. */ + /* This is a "negative" flag so the tests are reversed */ + (S_ISNO_SHAREAS(st->st_mode,st->st_genvalue))? + fprintf(stream," NO "): fprintf(stream," YES "); + + /* HFSBD_AAUD_READ - auditor read setting */ + if ((st->st_auditoraudit & (AUDTREADFAIL+AUDTREADSUCC)) + == (AUDTREADFAIL+AUDTREADSUCC) ) + tempval = "ALL "; + else if (st->st_auditoraudit & AUDTREADFAIL) + tempval = "FAIL "; + else if (st->st_auditoraudit & AUDTREADSUCC) + tempval = "SUCCESS "; + else + tempval = "NONE "; + fprintf(stream," %s",tempval); + /* HFSBD_AAUD_WRITE - auditor write setting */ + if ((st->st_auditoraudit & (AUDTWRITEFAIL+AUDTWRITESUCC)) + == (AUDTWRITEFAIL+AUDTWRITESUCC) ) + tempval = "ALL "; + else if (st->st_auditoraudit & AUDTWRITEFAIL) + tempval = "FAIL "; + else if (st->st_auditoraudit & AUDTWRITESUCC) + tempval = "SUCCESS "; + else + tempval = "NONE "; + fprintf(stream," %s",tempval); + /* HFSBD_AAUD_EXEC - auditor execute setting */ + if ((st->st_auditoraudit & (AUDTEXECFAIL+AUDTEXECSUCC)) + == (AUDTEXECFAIL+AUDTEXECSUCC) ) + tempval = "ALL "; + else if (st->st_auditoraudit & AUDTEXECFAIL) + tempval = "FAIL "; + else if (st->st_auditoraudit & AUDTEXECSUCC) + tempval = "SUCCESS "; + else + tempval = "NONE "; + fprintf(stream," %s",tempval); + + /* HFSBD_UAUD_READ - owner read setting */ + if ((st->st_useraudit & (AUDTREADFAIL+AUDTREADSUCC)) + == (AUDTREADFAIL+AUDTREADSUCC) ) + tempval = "ALL "; + else if (st->st_useraudit & AUDTREADFAIL) + tempval = "FAIL "; + else if (st->st_useraudit & AUDTREADSUCC) + tempval = "SUCCESS "; + else + tempval = "NONE "; + fprintf(stream," %s",tempval); + /* HFSBD_UAUD_WRITE - owner write setting */ + if ((st->st_useraudit & (AUDTWRITEFAIL+AUDTWRITESUCC)) + == (AUDTWRITEFAIL+AUDTWRITESUCC) ) + tempval = "ALL "; + else if (st->st_useraudit & AUDTWRITEFAIL) + tempval = "FAIL "; + else if (st->st_useraudit & AUDTWRITESUCC) + tempval = "SUCCESS "; + else + tempval = "NONE "; + fprintf(stream," %s",tempval); + /* HFSBD_UAUD_EXEC - owner execute setting */ + if ((st->st_useraudit & (AUDTEXECFAIL+AUDTEXECSUCC)) + == (AUDTEXECFAIL+AUDTEXECSUCC) ) + tempval = "ALL "; + else if (st->st_useraudit & AUDTEXECFAIL) + tempval = "FAIL "; + else if (st->st_useraudit & AUDTEXECSUCC) + tempval = "SUCCESS "; + else + tempval = "NONE "; + fprintf(stream," %s",tempval); + + /* HFSBD_AUDIT_ID - RACF audit id for this file */ + fprintf(stream," "); + for (i=0;ist_auditid);++i) + fprintf(stream,"%02X",(int)st->st_auditid??(i??));/* + @P1C*/ + + /* HFSBD_FID - file identifier */ + fprintf(stream," "); + for (i=0;ist_fid);++i) + fprintf(stream,"%02X",(int)st->st_fid??(i??)); /*@P1C*/ + + /* HFSBD_CREATE_DATE - file create date */ + timeptr = localtime(&st->st_createtime); + ch = strftime(dest,sizeof(dest),"%Y-%m-%d",timeptr); + fprintf(stream," %s",dest); + /* HFSBD_CREATE_TIME - file create time */ + ch = strftime(dest,sizeof(dest),"%H:%M:%S",timeptr); + fprintf(stream," %s",dest); + /* HFSBD_LASTREF_DATE - file last access date */ + timeptr = localtime(&st->st_atime); + ch = strftime(dest,sizeof(dest),"%Y-%m-%d",timeptr); + fprintf(stream," %s",dest); + /* HFSBD_LASTREF_TIME - file last access date */ + ch = strftime(dest,sizeof(dest),"%H:%M:%S",timeptr); + fprintf(stream," %s",dest); + /* HFSBD_LASTCHG_DATE - file last status change date */ + timeptr = localtime(&st->st_ctime); + ch = strftime(dest,sizeof(dest),"%Y-%m-%d",timeptr); + fprintf(stream," %s",dest); + /* HFSBD_LASTCHG_TIME - file last status change date */ + ch = strftime(dest,sizeof(dest),"%H:%M:%S",timeptr); + fprintf(stream," %s",dest); + /* HFSBD_LASTDAT_DATE - file last data modification date */ + timeptr = localtime(&st->st_mtime); + ch = strftime(dest,sizeof(dest),"%Y-%m-%d",timeptr); + fprintf(stream," %s",dest); + /* HFSBD_LASTDAT_TIME - file last data modification date */ + ch = strftime(dest,sizeof(dest),"%H:%M:%S",timeptr); + fprintf(stream," %s",dest); + + /* HFSBD_NUMBER_LINKS - number of links to file */ + fprintf(stream," %010u",st->st_nlink); + + /* HFSBD_SHARELIB */ + (S_ISSHARE_LIB(st->st_mode, st->st_genvalue))? + fprintf(stream, " YES "): fprintf(stream, " NO "); + + /* Check for Access ACL */ + if (st->st_fspflag2&S_ACCESSACL) { + fprintf(stream, " YES "); + } + else fprintf(stream, " NO "); + + /* Check for file default ACL */ + if (st->st_fspflag2&S_FMODELACL){ + fprintf(stream, " YES "); + } + else fprintf(stream, " NO "); + + /* Check for directory default ACL */ + if (st->st_fspflag2&S_DMODELACL){ + fprintf(stream, " YES "); + } + else fprintf(stream, " NO "); + + /* HFSBD_SECLABEL @L2A*/ + if (st->st_seclabel) /* If not binary 0's @L2A*/ + fprintf(stream," %-8s",st->st_seclabel); /*@L2A*/ + else /*@L2A*/ + fprintf(stream, " "); /*@L2A*/ + + /*********************************************************/ + /* Output the file system data set name. If we had an */ + /* error obtaining the mount entry above, the devnum */ + /* will be set to 0, and we simply output blanks. @L5C*/ + /*********************************************************/ + if (devnum == 0) { /* If error obtaining mntent */ + fprintf(stream, " %-44.44s", " "); /* Blanks @L3A*/ + } + /* Write out the current file system data set name */ + else + fprintf(stream, " %-44.44s", fsname); /*@L3A*/ + + + /*********************************************************/ + /* If the file is a symlink, report its contents. This */ + /* works for external links as well. @L4A*/ + /*********************************************************/ + if (S_ISLNK(st->st_mode)) { + char symbuff??(1024??); /* Max=1023, + ending null @L4A*/ + int linksize = readlink(file, + symbuff, + sizeof(symbuff)); /*@L4A*/ + if (linksize < 0) { + perror("IRR67710I readlink() error\n"); /*@L4A*/ + fprintf(stream," %-1023.1023s"," "); /* Blanks @L4A*/ + } + else { + symbuff??(linksize??) = 0; /* Add null at end @L4A*/ + fprintf(stream," %-1023.1023s", symbuff); /*@L4A*/ + } + } + else + fprintf(stream," %-1023.1023s"," "); /* Blanks @L4A*/ + + + /*********************************************************/ + /* Done with basic data record!!! */ + /* Add a newline character at end of record */ + /*********************************************************/ + fprintf(stream,"\n"); + + + /*********************************************************/ + /* Now unload ACL information. */ + /*********************************************************/ + + /* Check for Access ACL */ + if (st->st_fspflag2&S_ACCESSACL) + ACL_Info(file, ACL_ACCESS, st, 901); + + /* Check for file default ACL */ + if (st->st_fspflag2&S_FMODELACL) + ACL_Info(file, ACL_FILDEF, st, 902); + + /* Check for directory default ACL */ + if (st->st_fspflag2&S_DMODELACL) + ACL_Info(file, ACL_DIRDEF, st, 903); + + break; + + + default: + break; + } + return (0); +} + +/**********************************************************************/ +/* mapit: */ +/* Map the input uid to a RACF user ID, or an input gid to a RACF */ +/* group name. A local cache is maintained. It contains the */ +/* mappings for the 10 most recently encountered uids and gids. */ +/* When a match is found, it is moved to the front of the linked */ +/* list. When a new entry is needed, it is placed at the head of */ +/* the list, and if maxcache entries already exist, the last one */ +/* is removed. Because files within a directory generally have the */ +/* same owner, this should drastically reduce the number of calls */ +/* to the user/group database, and hence, pathlength and RACF I/O. */ +/**********************************************************************/ +char* +mapit(const char idtype, int idvalue) +{ + int match = 0; + int toobig = 0; + struct passwd *p; + struct group *grp; + struct cachelem **cacheptr; /* ptr to head of relevant cache */ + struct cachelem *tempptr; /* ptr to current cache element */ + + /* Get cache type appropriate to input type (user or group) */ + if (idtype == usertype) + cacheptr = &uidcache; + else + cacheptr = &gidcache; + + /* Scan the cache for a match on the input uid/gid */ + for (tempptr = *cacheptr ; tempptr ; tempptr = tempptr->next) { + + if (tempptr->id == idvalue) + { + strcpy(outvalue,tempptr->name); + /* If the cache element is not already at the head of the list, + move it there now. */ + if (tempptr != *cacheptr) + { + /* Dequeue the matched element */ + (tempptr->prev)->next = tempptr->next; + (tempptr->next)->prev = tempptr->prev; + /* Insert matched element at head of queue */ + tempptr->prev = (*cacheptr)->prev; + tempptr->next = *cacheptr; + ((*cacheptr)->prev)->next = tempptr; + (*cacheptr)->prev = tempptr; + *cacheptr = tempptr; + } + match = 1; + break; + } + + /* Bail out if we've come full circle in the linked list */ + if (tempptr->next == *cacheptr) + break; + } + + /* If no match was found, call to map the id to a name. Create a */ + /* new cache element and insert it at the front of the list. */ + if (!match) + { + /* Map the id to a name */ + if (idtype == usertype) + if ((p = getpwuid(idvalue)) == NULL) + strcpy(outvalue," "); + else + strcpy(outvalue,p->pw_name); + else + if ((grp = getgrgid(idvalue)) == NULL) + strcpy(outvalue," "); + else + strcpy(outvalue,grp->gr_name); + + /* Create a new cache element */ + tempptr = (struct cachelem*)malloc(sizeof(struct cachelem)); + tempptr->id = idvalue; + strcpy(tempptr->name,outvalue); + + /* If the cache exists, insert new element as 1st element */ + if (*cacheptr) + { + /* Set new element's next and prev ptrs */ + tempptr->prev = (*cacheptr)->prev; + tempptr->next = *cacheptr; + /* Set last element's prev ptr to new element */ + ((*cacheptr)->prev)->next = tempptr; + /* Set original first's prev ptr to new element */ + (*cacheptr)->prev = tempptr; + /* Set cache head to new element */ + *cacheptr = tempptr; + /* increment the cache counter */ + if (idtype == usertype) + if (uidcount < maxcache) + ++uidcount; + else + toobig = 1; + else + if (gidcount < maxcache) + ++gidcount; + else + toobig = 1; + + /* If maxcache elements has been exceeded, dequeue and free the + last element. */ + if (toobig) + { + tempptr = (*cacheptr)->prev; + (tempptr->prev)->next = tempptr->next; + (tempptr->next)->prev = tempptr->prev; + free(tempptr); + } + } + /* Nothing in cache yet. Initialize cache ptr to this new element, + and set the element's next and prev ptr to itself. */ + else + { + *cacheptr = tempptr; + tempptr->next = tempptr; + tempptr->prev = tempptr; + if (idtype == usertype) + uidcount = 1; + else + gidcount = 1; + } + } + + return(outvalue); + } + +/**********************************************************************/ +/* FS_Info: */ +/* Create a type 0904 record for every mounted file system. */ +/* We use w_getmntent to iteratively obtain a chunk of mount */ +/* ta ble entries. We create a Type 0904 record for each */ +/* returned entry. @L5A*/ +/**********************************************************************/ +int FS_Info(){ + + int p2_ret; + char *mountmode; + + int entries; /* Number of mount entries returned */ + int tot_entries = 0; /* Total number of mounted file systems @P4A*/ + int entry; /* Index into mount table */ + struct { + MNTE3H header; + W_MNTENT3 mount_table??(100??); + } work_area; /* Buffer to contain 100 entries @P4C*/ + W_MNTENT3 *tabentry; /* Pointer to a mount table entry */ + + + /* Clear the buffer storage @P4C*/ + memset(&work_area, 0x00, sizeof(work_area)); + /* 'header' initialization to specify MNTE3 mapping format @P4C*/ + memcpy(work_area.header.mnt3H_cbid, MNTE3H_ID, 4); + work_area.header.mnt3H_cblen = sizeof(struct mnte3); + work_area.header.mnt3H_bodylen = sizeof(struct w_mntent3); + + /*******************************************************************/ + /* Iteratively obtain 100 entries at a time. @P4A*/ + /*******************************************************************/ + do { /* While there are still entries to process @P4A*/ + if ((entries = w_getmntent((char *) &work_area, + sizeof(work_area))) == -1) + perror("w_getmntent() error"); + + /*****************************************************************/ + /* Loop for the number of returned entries, creating a type */ + /* 904 record for each entry. */ + /*****************************************************************/ + else { /* No error */ + /*fprintf(stdout,"There are %d entries returned\n", entries);*/ + tot_entries+=entries; /* add number returned to total @P4A*/ + + for (entry=0; entrymnt3_fsname); + + /* HFMFS_TYPE - File system type */ + fprintf(stream, " %-8.8s", tabentry->mnt3_fstname); + + /* HFMFS_INODE - the root inode - Doesn't seem very useful? */ + /*fprintf(stream, " %010u", tabentry->mnt3_rootino);*/ + + /* HFMFS_MODE - mount mode: READONLY or READWRITE */ + if (tabentry->mnt3_mode.mntentfsmoderdonly) + mountmode="READONLY "; + else + mountmode="READWRITE "; + fprintf(stream," %s",mountmode); + + /* HFMFS_SECURITY- mount mode: SECURITY or NOSECURITY */ + if (tabentry->mnt3_mode.mntentfsmodenosec) + mountmode="NOSECURITY"; + else + mountmode="SECURITY "; + fprintf(stream," %s",mountmode); + + /* HFMFS_SETUID - mount mode: SETUID or NOSETUID */ + if (tabentry->mnt3_mode.mntentfsmodenosuid) + mountmode="NOSETUID "; + else + mountmode="SETUID "; + fprintf(stream," %s",mountmode); + + /* HFMFS_MUID - mounting UID */ + #if __EDC_TARGET > __EDC_LE410C /* Must be >= z/OS R13 @P3C*/ + fprintf(stream," %010u", tabentry->mnt3_fsusrmntUID); + + /* HFMFS_MUSER - corresponding RACF user ID */ + fprintf(stream," %-8s", mapit(usertype, + tabentry->mnt3_fsusrmntUID)); + #else /* Lower than R13, just print blanks */ + fprintf(stream," "); + #endif /* __EDC_LE410C */ /*@P3C*/ + + /* HFMFS_MOUNTPOINT - path name of mount point */ + fprintf(stream," %-1023.1023s", tabentry->mnt3_mountpoint); + + fprintf(stream, "\n"); + + } /* For each returned entry */ + } /* No w_getmntent() error */ + } while (entries > 0); /* Iterate if any entries were returned @P4A*/ + +/*fprintf(stdout,"There were %d total entries returned\n", + tot_entries); +*/ + return (0); +} /*@L5A*/ + +/**********************************************************************/ +/* ACL_Info: */ +/* Extracting information from a Access ACL */ +/* Process is similar to the unload function. The */ +/* sys/acl.h and sys/stat.h libraries are utilized */ +/* in this function. */ +/* */ +/* Also if -c was specified the function will remove */ +/* ACL references that do not map to a user or group. */ +/**********************************************************************/ +int ACL_Info(const char *file,acl_type_t type_d,const struct stat *st, + int aclType){ + lacl_t acl_d, acl_delete; + acl_entry_t entry_d; + int ret_num; + struct passwd *p; + struct group *grp; + + acl_delete = acl_init(1024); + + if ((acl_d=Get_acl(file, type_d, &ret_num)) == NULL) { + return(1); + } + while (acl_get_entry(acl_d, &entry_d)==1) { + + /* TYPE_RECORD_TYPE */ + fprintf(stream, "0%d", aclType); + + + /* TYPE_NAME - path name of file being unloaded */ + fprintf(stream," %-1023.1023s",file); + + /* TYPE_INODE */ + fprintf(stream, " %010u", st->st_ino); + + /* TYPE_TYPE */ + if (entry_d->acle_type == ACL_USER) + fprintf(stream, " USER "); + else if (entry_d->acle_type == ACL_GROUP) + fprintf(stream, " GROUP "); + + + /* TYPE_ID */ + fprintf(stream, " %010u", entry_d->acle_id); + + /* TYPE_ID_NAME */ + if (entry_d->acle_type == ACL_USER) { + fprintf(stream, " %-8s", mapit(usertype, entry_d->acle_id)); + } + + else if (entry_d->acle_type == ACL_GROUP) { + fprintf(stream, " %-8s", mapit(grouptype, entry_d->acle_id)); + } + + + /* TYPE_READ */ + if (entry_d->acle_value.aclp_read==1) + fprintf (stream, " YES "); + else fprintf (stream, " NO "); + + /* TYPE_WRITE */ + if (entry_d->acle_value.aclp_write==1) + fprintf (stream, " YES "); + else fprintf (stream, " NO "); + + /* TYPE_EXECUTE */ + if (entry_d->acle_value.aclp_execute==1) + fprintf (stream, " YES "); + else fprintf (stream, " NO "); + + /* Inserting ACL entries into buffer that need to be deleted */ + if (entry_d->acle_type == ACL_USER) { + if ((p = getpwuid(entry_d->acle_id))==NULL && cleanup==1){ + entry_delete_counter ++; + acl_create_entry(&acl_delete, entry_d, ACL_VER_1); + } + } + + else if (entry_d->acle_type == ACL_GROUP) { + if ((grp = getgrgid(entry_d->acle_id))==NULL && cleanup==1){ + entry_delete_counter++; + acl_create_entry(&acl_delete, entry_d, ACL_VER_1); + } + } + + fprintf(stream, "\n"); + + } + /* Deleting ACL entries */ + acl_set_file(file, type_d, acl_delete, ACL_DELETE, &entry_d); + acl_free(acl_delete); + + return (0); + } + +/**********************************************************************/ +/* Get_acl: */ +/* Function contructs the ACL buffer from the file provided. */ +/* the ACL is returned, if there was no entry NULL is returned */ +/**********************************************************************/ +static lacl_t Get_acl (char const *file,acl_type_t type_d,int *ret_num){ + static lacl_t acl_d = NULL; + char *string; + int rc; + int num, num2; + + *ret_num = 0; + + /* call acl_init() to get ACL buffer */ + if (acl_d == NULL) + if ((acl_d = acl_init(1024)) == NULL) + return (NULL); + + /*Check buffer */ + rc = acl_get_file(file, type_d, acl_d, &num); + + /*Checking for error from acl_get_file */ + if (rc < 0 && type_d==ACL_ACCESS) { + perror("IRR67705I acl_get_file() error\n"); + fprintf(stderr,"IRR67706I Error retrieving the ACCESS ACL" \ + " for the file %s \n", file); + return(NULL); + } + if (rc < 0 && type_d==ACL_FILDEF) { + perror("IRR67705I acl_get_file() error\n"); + fprintf(stderr,"IRR67706I Error retrieving the FILE DEFAULT ACL" \ + " for the file %s \n", file); + return(NULL); + } + if (rc < 0 && type_d==ACL_DIRDEF) { + perror("IRR67705I acl_get_file() error\n"); + fprintf(stderr,"IRR67706I Error retrieving the DIRECTORY" \ + " DEFAULT ACL for the file %s \n", file); + return(NULL); + } + /* if acl_get_file() was successful */ + return (acl_d); + + }