/* * Copyright (c) 1998 Denis Perchine * Copyright (c) 2004 Szombathelyi György * Former maintainer: Adriaan de Groot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. **/ #include "globals.h" #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "kglobal_.h" #include "kgroupfiles.h" #include "misc.h" #include "editDefaults.h" KGroupFiles::KGroupFiles( KUserPrefsBase *cfg ) : KGroups( cfg ) { gs_backuped = FALSE; gr_backuped = FALSE; gn_backuped = FALSE; smode = 0400; mode = 0644; uid = 0; gid = 0; caps = Cap_Passwd; reload(); } KGroupFiles::~KGroupFiles() { mGroups.clear(); } bool KGroupFiles::reload() { struct group *p; KU::KGroup *tmpKG = 0; struct stat st; TQString filename; TQString group_filename; TQString nisgroup_filename; int rc = 0; int group_errno = 0; int nisgroup_errno = 0; char processing_file = '\0'; #define GROUP 0x01 #define NISGROUP 0x02 #define MAXFILES 2 // Prepare to read KUser configuration group_filename = mCfg->groupsrc(); nisgroup_filename = mCfg->nisgroupsrc(); if(!group_filename.isEmpty()) { processing_file = processing_file | GROUP; filename.append(group_filename); } // Start reading group file(s) for(int k = 0; k < MAXFILES; k++) { rc = stat(TQFile::encodeName(filename), &st); if(rc != 0) { KMessageBox::error( 0, i18n("stat call on file %1 failed: %2\nCheck KUser settings."). arg(filename).arg(TQString::fromLatin1(strerror(errno))) ); if( (processing_file & GROUP) != 0 ) { group_errno = errno; if(!nisgroup_filename.isEmpty()) { processing_file = processing_file & ~GROUP; processing_file = processing_file | NISGROUP; filename.truncate(0); filename.append(nisgroup_filename); } continue; } else{ nisgroup_errno = errno; break; } } mode = st.st_mode; uid = st.st_uid; gid = st.st_gid; // We are reading our configuration specified group file #ifdef HAVE_FGETGRENT FILE *fgrp = fopen(TQFile::encodeName(filename), "r"); TQString tmp; if (fgrp == NULL) { KMessageBox::error( 0, i18n("Error opening %1 for reading.").arg(filename) ); return FALSE; } while ((p = fgetgrent(fgrp)) != NULL) { #else setgrent(); while ((p = getgrent()) != NULL) { #endif tmpKG = new KU::KGroup(); tmpKG->setGID(p->gr_gid); tmpKG->setName(TQString::fromLocal8Bit(p->gr_name)); tmpKG->setPwd(TQString::fromLocal8Bit(p->gr_passwd)); char *u_name; int i = 0; while ((u_name = p->gr_mem[i])!=0) { tmpKG->addUser(TQString::fromLocal8Bit(u_name)); i++; } mGroups.append(tmpKG); } // End reading filename #ifdef HAVE_FGETGRENT fclose(fgrp); #else endgrent(); #endif if(!nisgroup_filename.isEmpty()) { if(nisgroup_filename == group_filename) break; processing_file = processing_file & ~GROUP; processing_file = processing_file | NISGROUP; filename.truncate(0); filename.append(nisgroup_filename); } else break; } // end of processing files, for loop if( (group_errno == 0) && (nisgroup_errno == 0) ) return(TRUE); if( (group_errno != 0) && (nisgroup_errno != 0) ) return(FALSE); else return(TRUE); } bool KGroupFiles::save() { kdDebug() << "KGroupFiles::save() " << endl; FILE *group_fd = NULL; FILE *gshadow_fd = NULL; FILE *nisgroup_fd = NULL; gid_t mingid = 0; int nis_groups_written = 0; gid_t tmp_gid = 0; TQString tmpGe, tmpSe, tmp2; TQString group_filename, new_group_filename; TQString gshadow_filename, new_gshadow_filename; TQString nisgroup_filename, new_nisgroup_filename; char errors_found = '\0'; #define NOMINGID 0x01 #define NONISGROUP 0x02 // read KUser configuration info group_filename = mCfg->groupsrc(); new_group_filename = group_filename + TQString::fromLatin1(KU_CREATE_EXT); #ifdef HAVE_SHADOW gshadow_filename = mCfg->gshadowsrc(); if ( !TDEStandardDirs::exists( gshadow_filename ) ) gshadow_filename = TQString(); else new_gshadow_filename = gshadow_filename + TQString::fromLatin1(KU_CREATE_EXT); #endif nisgroup_filename = mCfg->nisgroupsrc(); new_nisgroup_filename = nisgroup_filename + TQString::fromLatin1(KU_CREATE_EXT); if( nisgroup_filename != group_filename ) { mingid = mCfg->nismingid(); } // Backup file(s) if(!group_filename.isEmpty()) { if (!gr_backuped) { if ( !backup(group_filename) ) return false; gr_backuped = TRUE; } } if(!gshadow_filename.isEmpty()) { if (!gs_backuped) { if ( !backup(gshadow_filename) ) return false; gs_backuped = TRUE; } } if(!nisgroup_filename.isEmpty() && (nisgroup_filename != group_filename)) { if (!gn_backuped) { if ( !backup(nisgroup_filename) ) return false; gn_backuped = TRUE; } } // Open file(s) if(!group_filename.isEmpty()) { if((group_fd = fopen(TQFile::encodeName(new_group_filename), "w")) == NULL) { KMessageBox::error( 0, i18n("Error opening %1 for writing.").arg(new_group_filename) ); return false; } } if(!gshadow_filename.isEmpty()) { if((gshadow_fd = fopen(TQFile::encodeName(new_gshadow_filename), "w")) == NULL) { KMessageBox::error( 0, i18n("Error opening %1 for writing.").arg(new_gshadow_filename) ); if ( group_fd ) fclose ( group_fd ); return false; } } if(!nisgroup_filename.isEmpty() && (nisgroup_filename != group_filename)) { if((nisgroup_fd = fopen(TQFile::encodeName(new_nisgroup_filename), "w")) == NULL) { KMessageBox::error( 0, i18n("Error opening %1 for writing.").arg(new_nisgroup_filename) ); if ( group_fd ) fclose ( group_fd ); if ( gshadow_fd ) fclose ( gshadow_fd ); return false; } } TQPtrListIterator it( mGroups ); KU::KGroup *gr; bool addok = false; gr = (*it); while (true) { if ( gr == 0 ) { if ( addok ) break; it = TQPtrListIterator ( mAdd ); gr = (*it); addok = true; if ( gr == 0 ) break; }; if ( mDel.containsRef( gr ) ) { ++it; gr = (*it); continue; } if ( mMod.contains( gr ) ) gr = &( mMod[ gr ] ); #ifdef HAVE_SHADOW if ( addok && !mCfg->gshadowsrc().isEmpty() ) gr->setPwd("x"); #endif tmpGe = gr->getName(); tmpGe.replace( ',', "_" ); tmpGe.replace( ':', "_" ); gr->setName( tmpGe ); tmp_gid = gr->getGID(); tmpGe += ":" + gr->getPwd() + ":" + TQString::number( gr->getGID() ) + ":"; tmpSe = gr->getName() + ":!::"; for (uint j=0; jcount(); j++) { if (j != 0) { tmpGe += ','; tmpSe += ','; } gr->user( j ).replace( ',', "_" ); gr->user( j ).replace( ':', "_" ); tmpGe += gr->user( j) ; tmpSe += gr->user( j ); } tmpGe += '\n'; tmpSe += '\n'; if( (nisgroup_fd != 0) && (mingid != 0) ) { if(mingid <= tmp_gid) { fputs(tmpGe.local8Bit(), nisgroup_fd); nis_groups_written++; ++it; gr = (*it); continue; } } if( (nisgroup_fd != 0) && (mingid == 0) ) { errors_found = errors_found | NOMINGID; } if( (nisgroup_fd == 0) && (mingid != 0) ) { errors_found = errors_found | NONISGROUP; } fputs( tmpGe.local8Bit(), group_fd ); if ( gshadow_fd ) fputs( tmpSe.local8Bit(), gshadow_fd ); ++it; gr = (*it); } if(group_fd) { fclose(group_fd); chmod(TQFile::encodeName(new_group_filename), mode); chown(TQFile::encodeName(new_group_filename), uid, gid); rename(TQFile::encodeName(new_group_filename), TQFile::encodeName(group_filename)); } if(gshadow_fd) { fclose(gshadow_fd); chmod(TQFile::encodeName(new_gshadow_filename), mode); chown(TQFile::encodeName(new_gshadow_filename), uid, gid); rename(TQFile::encodeName(new_gshadow_filename), TQFile::encodeName(gshadow_filename)); } if(nisgroup_fd) { fclose(nisgroup_fd); chmod(TQFile::encodeName(nisgroup_filename), mode); chown(TQFile::encodeName(nisgroup_filename), uid, gid); rename(TQFile::encodeName(new_nisgroup_filename), TQFile::encodeName(nisgroup_filename)); } if( (errors_found & NOMINGID) != 0 ) { KMessageBox::error( 0, i18n("Unable to process NIS group file without a minimum GID specified.\nPlease update KUser settings (File Source Settings).") ); } if( (errors_found & NONISGROUP) != 0 ) { KMessageBox::error( 0, i18n("Specifying NIS minimum GID requires NIS file(s).\nPlease update KUser settings (File Source Settings).") ); } #ifdef GRMKDB if( (nis_groups_written > 0) || (nisgroup_filename == group_filename) ) { if (system(GRMKDB) != 0) { KMessageBox::error( 0, i18n("Unable to build NIS group databases.") ); return FALSE; } } #endif return TRUE; } bool KGroupFiles::dbcommit() { bool ret; mode_t mode; kdDebug() << "KGroupFiles dbcommit" << endl; mAddSucc.clear(); mDelSucc.clear(); mModSucc.clear(); if ( mDel.isEmpty() && mAdd.isEmpty() && mMod.isEmpty() ) return true; mode = umask(0077); ret = save(); umask( mode ); if ( !ret ) return false; mDelSucc = mDel; mAddSucc = mAdd; mModSucc = mMod; mDel.clear(); mAdd.clear(); mMod.clear(); return true; }