Esempio n. 1
0
void ExtractACLNew(Archive &Arc,char *FileName,wchar *FileNameW)
{
#if defined(_XBOX) || defined(_LINUX) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP))
  return;
#else
  if (!WinNT())
    return;

  Array<byte> SubData;
  if (!Arc.ReadSubData(&SubData,NULL))
    return;

  SetPrivileges();

  SECURITY_INFORMATION  si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
                           DACL_SECURITY_INFORMATION;
  if (ReadSacl)
    si|=SACL_SECURITY_INFORMATION;
  SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0];

  int SetCode;
  if (FileNameW!=NULL)
    SetCode=SetFileSecurityW(FileNameW,si,sd);
  else
    SetCode=SetFileSecurity(FileName,si,sd);

  if (!SetCode)
  {
    RarLog(Arc.FileName,St(MACLSetError),FileName);
    ErrHandler.SysErrMsg();
    ErrHandler.SetErrorCode(WARNING);
  }
#endif
}
Esempio n. 2
0
void ExtractACLNew(Archive &Arc,char *FileName,wchar *FileNameW)
{
  if (!WinNT())
    return;

  Array<byte> SubData;
  if (!Arc.ReadSubData(&SubData,(File *) NULL))
    return;

  SetPrivileges();

  SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
                          DACL_SECURITY_INFORMATION;
  if (ReadSacl)
    si|=SACL_SECURITY_INFORMATION;
  SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0];

  int SetCode;
  if (FileNameW!=NULL)
    SetCode=SetFileSecurityW(FileNameW,si,sd);
  else
    SetCode=SetFileSecurityA(FileName,si,sd);

  if (!SetCode)
  {
    Log(Arc.FileName,St(MACLSetError),FileName);
    ErrHandler.SysErrMsg();
    ErrHandler.SetErrorCode(WARNING);
  }
}
Esempio n. 3
0
void ExtractACL(Archive &Arc,char *FileName,wchar *FileNameW)
{
  if (!WinNT())
    return;

  SetPrivileges();

  if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
  {
    Log(Arc.FileName,St(MACLBroken),FileName);
    ErrHandler.SetErrorCode(CRC_ERROR);
    return;
  }

  if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
  {
    Log(Arc.FileName,St(MACLUnknown),FileName);
    ErrHandler.SetErrorCode(WARNING);
    return;
  }

  ComprDataIO DataIO;
  Unpack Unpack(&DataIO);
  Unpack.Init();

  Array<byte> UnpData(Arc.EAHead.UnpSize);
  DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
  DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
  DataIO.EnableShowProgress(false);
  DataIO.SetFiles(&Arc,NULL);
  Unpack.SetDestSize(Arc.EAHead.UnpSize);
  Unpack.DoUnpack(Arc.EAHead.UnpVer,false);

  if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
  {
    Log(Arc.FileName,St(MACLBroken),FileName);
    ErrHandler.SetErrorCode(CRC_ERROR);
    return;
  }

  SECURITY_INFORMATION  si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
                           DACL_SECURITY_INFORMATION;
  if (ReadSacl)
    si|=SACL_SECURITY_INFORMATION;
  SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0];

  int SetCode;
  if (FileNameW!=NULL)
    SetCode=SetFileSecurityW(FileNameW,si,sd);
  else
    SetCode=SetFileSecurityA(FileName,si,sd);

  if (!SetCode)
  {
    Log(Arc.FileName,St(MACLSetError),FileName);
    ErrHandler.SysErrMsg();
    ErrHandler.SetErrorCode(WARNING);
  }
}
int main(int argc, char *argv[])
{
    FILE *usersFilePtr = NULL, *tempUsersFilePtr = NULL, *passFilePtr = NULL, *groupsFilePtr = NULL;
    //char line[MAX_STRING_LEN + 1];
    char line[MAX_LINE_LEN];
    char lineFromFile[MAX_LINE_LEN];
    char usernameFromFile[MAX_STRING_LEN + 1];
    char realmFromFile[MAX_STRING_LEN + 1];
    int found;
    int result;
    static char choice[81];

    int doCreateNewFile = 0;
    int doDeleteUser = 0;
	int addUserToGroup = 0;
	int deleteUserFromGroup = 0;
	int createGroup = 0;
	int deleteGroup = 0;
    int confirmPotentialDamage = 1;
    char* qtusersFilePath = NULL;
	char* qtgroupsFilePath = NULL;
    char* userName = NULL;
	char* groupName = NULL;
    char* realmString = NULL;
    char* password = NULL;
    char* passwordFilePath = NULL;
    int ch;
    extern char* optarg;
    extern int optind;

	/* Read command line arguments */
    while ((ch = getopt(argc, argv, "f:cg:r:p:P:A:D:C:R:dFhv?")) != EOF)
    {
        switch(ch) 
        {

            case 'f':
                    qtusersFilePath = CopyString(optarg);
            break;
			
            case 'c':
                    doCreateNewFile = 1;
            break;
			
            case 'g':
                    qtgroupsFilePath = CopyString(optarg);
            break;
			
            case 'r':
                    realmString = CopyString(optarg);
                    if (::strlen(realmString) > MAX_STRING_LEN)
                    {
                        qtss_fprintf(stderr, "Realm cannot have more than %d characters.\n", MAX_STRING_LEN);
                        qtss_printf("Exiting! \n");
                        exit(1);
                    }
            break;

            case 'p':
                    password = CopyString(optarg);
					::memset(optarg, 0, ::strlen(optarg));
					
                    if (::strlen(password) > MAX_PASSWORD_LEN)
                    {
                        qtss_fprintf(stderr, "Password cannot have more than %d characters.\n", MAX_PASSWORD_LEN);
                        qtss_printf("Exiting! \n");
                        exit(1);
                    }
            break;

            case 'P':
                    passwordFilePath = CopyString(optarg);
            break;

            case 'A':
                    groupName = CopyString(optarg);
					addUserToGroup = 1;
            break;

            case 'D':
                    groupName = CopyString(optarg);
					deleteUserFromGroup = 1;
            break;

            case 'C':
                    groupName = CopyString(optarg);
					createGroup = 1;
            break;

            case 'R':
                    groupName = CopyString(optarg);
					deleteGroup = 1;
            break;			

            case 'd':
                    doDeleteUser = 1;
            break;
			
            case 'F':
                    confirmPotentialDamage = 0;
            break;

        case 'h':
        case 'v':
            case '?':
            default:
                usage(); 
            break;
        }
    }

	/* If password is to be read from a file, check validity of the password */
	if ((password == NULL) && (passwordFilePath != NULL))
    {
		if ((passFilePtr = fopen(passwordFilePath, "r")) != NULL ) 
		{
			char passline[MAX_STRING_LEN];
			char passFromFile[MAX_STRING_LEN];
			int passLen = 0;
			
			::memset(passline, 0, MAX_STRING_LEN);
			::memset(passFromFile, 0, MAX_STRING_LEN);
			
			GetLine(passline, MAX_STRING_LEN, passFilePtr);
	
			if (passline[0] == '\'')        // if it is single quoted, read until the end single quote
				GetWord(passFromFile, (passline + 1), '\'');
			else if (passline[0] == '"')        // if it is double quoted, read until the end double quote
				GetWord(passFromFile, (passline + 1), '"');
			else                    // if it is not quoted, read until the first whitespace
				GetWord(passFromFile, passline, ' ');
				
			passLen = ::strlen(passFromFile);
				
			if (passLen == 0)
			{
				qtss_fprintf(stderr, "Password in file %s is blank.\n", passwordFilePath);
				qtss_printf("Exiting! \n");
				exit(1);
			}
			else if (passLen > MAX_PASSWORD_LEN)
			{
				qtss_fprintf(stderr, "Password in file %s has more than %d characters. Cannot accept password.\n", passwordFilePath, MAX_PASSWORD_LEN);
				qtss_printf("Exiting! \n");
				exit(1);
			}
			else
				password = CopyString(passFromFile);

            fclose(passFilePtr);
        }
    }

    /* deleting a user and (creating a file or setting a password) don't make sense together */
    if ( doDeleteUser && (doCreateNewFile || password != NULL) )
    {
		qtss_fprintf(stderr, "Cannot use the -c option (to create the file) with the -d option (to delete the user).\n");
		qtss_printf("Exiting! \n");
        usage();
    }

    /* realm name only makes sense when creating a new password file */
    if ( !doCreateNewFile && (realmString != NULL) )
    {
		qtss_fprintf(stderr, "Can use the -r option only with the -c option (when creating the file).\n");
		qtss_printf("Exiting! \n");
		usage();
    }

	/* group name checks */
	if (groupName != NULL) 
	{
		/* check length < MAX_STRING_LEN */
		if (::strlen(groupName) > MAX_STRING_LEN)
		{
			qtss_fprintf(stderr, "Group name cannot have more than %d characters.\n", MAX_STRING_LEN);
			qtss_printf("Exiting! \n");
			exit(1);
		}	
		
		/* check for : */
        if (strchr(groupName, ':') != NULL) 
        {
            qtss_printf("Group name cannot contain a ':' character.\n");
			qtss_printf("Exiting! \n");
			exit(1);
        }
		
		/* can't add user to group and delete user from a group at the same time */
		if (addUserToGroup && deleteUserFromGroup)
        {
            qtss_printf("Cannot add to or delete from a group at the same time (use either -A or -D option, not both!).\n");
			qtss_printf("Exiting! \n");
			exit(1);
        }
		
		/* can't create and delete group at the same time */
		if (createGroup && deleteGroup)
        {
            qtss_printf("Cannot create new group and delete group at the same time (use either -C or -R option, not both!).\n");
			qtss_printf("Exiting! \n");
			exit(1);
        }
	}

	/* Read in the username */
    if (argv[optind] != NULL)
    {
		/* If group needs to be created or deleted, username will be ignored. */
		if (createGroup || deleteGroup)
		{
			qtss_fprintf(stderr, "Warning: username cannot be specified with -C or -R option and will be ignored!\n");
		}
		else
		{
			userName = CopyString(argv[optind]);
			
			/* check length < MAX_STRING_LEN */		
			if (::strlen(userName) > MAX_STRING_LEN)
			{
			qtss_fprintf(stderr, "Username cannot have more than %d characters.\n", MAX_STRING_LEN);
			qtss_printf("Exiting! \n");
			exit(1);
			}
		}
    }
    else
	{
		/* Exit if username is not given, unless a group has to be created or deleted. */
		if (!createGroup && !deleteGroup)
		{
			qtss_fprintf(stderr, "Username not given!\n");
			qtss_printf("Exiting! \n");
			usage();
		}
    }

    if (confirmPotentialDamage && doDeleteUser)
    {
        qtss_printf("Delete user %s (will also delete user from groups in the groups file)? y or n [y] ", userName);
        fgets( (char*)&choice, 80, stdin);
        if( choice[0] == 'n' || choice[0] == 'N' ) 
            exit(0);
    }

    if (qtusersFilePath == NULL)
    {
        qtusersFilePath = new char[strlen(kDefaultQTPasswdFilePath)+1];
        strcpy(qtusersFilePath, kDefaultQTPasswdFilePath);
    }

    if (qtgroupsFilePath == NULL)
    {
        qtgroupsFilePath = new char[strlen(kDefaultQTGroupsFilePath)+1];
        strcpy(qtgroupsFilePath, kDefaultQTGroupsFilePath);
    }
	
    if (realmString  == NULL)
    {
        char* kDefaultRealmString = "Streaming Server";

        realmString = new char[strlen(kDefaultRealmString)+1];
        strcpy(realmString, kDefaultRealmString);
    }

    
    tempUsersFile = NULL;
	tempGroupsFile = NULL;
	
#ifndef __Win32__
    signal(SIGINT, (void(*)(int))CleanupAndExit);
    //create file with owner RW permissions only
    umask(S_IRWXO|S_IRWXG);
#endif

    if (doCreateNewFile)
    {
        if (confirmPotentialDamage)
            if( (usersFilePtr = fopen(qtusersFilePath, "r")) != NULL ) 
            {
                fclose(usersFilePtr);
    
                qtss_printf("File already exists. Do you wish to overwrite it? y or n [y] ");
                fgets( (char*)&choice, 80, stdin);
                if( choice[0] == 'n' || choice[0] == 'N' ) 
                    CleanupAndExit();
                    
            }

        //create new file or truncate existing one to 0
        if ( (usersFilePtr = fopen(qtusersFilePath, "w")) == NULL)
        {   
			char buffer[kErrorStrSize];
            qtss_fprintf(stderr, "Could not open password file %s for writing. (err=%d %s)\n", qtusersFilePath, errno, qtss_strerror(errno, buffer, sizeof(buffer)));
            perror("fopen");
            CleanupAndExit();
        }

        qtss_printf("Creating password file for realm %s.\n", realmString);

        //write the realm into the file
        qtss_fprintf(usersFilePtr, "realm %s\n", realmString);

        fclose(usersFilePtr);
	    SetPrivileges(qtusersFilePath);


    }

#ifdef __Win32__
    char separator = '\\';
#else
    char separator = '/';
#endif
	char* tmpFile = "tmp.XXXXXX";
	char* alternateTempPath = "./tmp.XXXXXX";
    char* tempFilePath;
	int	tempFilePathLength = 0;
    char* lastOccurOfSeparator = strrchr(qtusersFilePath, separator);
    int pathLength = strlen(qtusersFilePath);
	
    if(lastOccurOfSeparator != NULL) 
    {
		int filenameLength = ::strlen(lastOccurOfSeparator) + sizeof(char);
		tempFilePathLength = pathLength - filenameLength + sizeof(char) + ::strlen(tmpFile);
		
		tempFilePath = new char[tempFilePathLength];
		memcpy(tempFilePath, qtusersFilePath, (pathLength - filenameLength));
		memcpy(tempFilePath + (pathLength - filenameLength), tmpFile, ::strlen(tmpFile));
		tempFilePath[pathLength - filenameLength + ::strlen(tmpFile)] = '\0';
		
		/* Get temp users file path name */
		if (!createGroup && !deleteGroup)
			tempUsersFile = GetTempFileAtPath(tempFilePath, tempFilePathLength);

		/* Get temp groups file path name */		
		if ((groupName != NULL) || doDeleteUser)
			tempGroupsFile = GetTempFileAtPath(tempFilePath, tempFilePathLength);
		
		delete [] tempFilePath;
    }
    else 
    {
		if (!createGroup && !deleteGroup)
			tempUsersFile = GetTempFileAtPath(alternateTempPath, ::strlen(alternateTempPath));
		if ((groupName != NULL) || doDeleteUser)
			tempGroupsFile = GetTempFileAtPath(alternateTempPath, ::strlen(alternateTempPath));
	}
		
	if ((groupName != NULL) && !(groupsFilePtr = fopen(qtgroupsFilePath, "r")))
	{
		char buffer[kErrorStrSize];
		qtss_fprintf(stderr, "Could not open groups file %s to manipulate groups file. (err=%d:%s)\n", qtgroupsFilePath, errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
				
		//create new file
        if ( (groupsFilePtr = fopen(qtgroupsFilePath, "w")) == NULL)
        {   
			char buffer[kErrorStrSize];
            qtss_fprintf(stderr, "Could not create a new groups file %s either. (err=%d %s)\n", qtgroupsFilePath, errno, qtss_strerror(errno, buffer, sizeof(buffer)));
			CleanupAndExit();
        }
		else
			qtss_printf("Created new groups file %s.\n", qtgroupsFilePath);

        fclose(groupsFilePtr);
	    SetPrivileges(qtgroupsFilePath);
	}
	
	if (createGroup)
	{
		AddOrDeleteGroup(1, groupName, qtgroupsFilePath, tempGroupsFile);
		qtss_printf("Created new group %s\n", groupName);
		return 0;
	}
	
	if (deleteGroup)
	{
		AddOrDeleteGroup(0, groupName, qtgroupsFilePath, tempGroupsFile);
		qtss_printf("Deleted group %s\n", groupName);
		return 0;
	}
	
    if (!(tempUsersFilePtr = fopen(tempUsersFile, "w"))) 
    {   
        char buffer[kErrorStrSize];
        qtss_printf("failed\n");
        qtss_fprintf(stderr, "Could not open temp users file. (err=%d %s)\n", errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
		CleanupAndExit();
    }
	
    if (!(usersFilePtr = fopen(qtusersFilePath, "r")))
    {   
        char buffer[kErrorStrSize];
        qtss_fprintf(stderr, "Could not open passwd file %s for reading. (err=%d:%s)\n", qtusersFilePath, errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
        qtss_fprintf(stderr, "Use -c option to create new one.\n");
		CleanupAndExit();
    }

    // Get the realm from the first line
    while (!(GetLine(line, MAX_LINE_LEN, usersFilePtr))) 
    {
        if ((line[0] == '#') || (!line[0]))
        {
            PutLine(tempUsersFilePtr, line);
            continue;
        }
        else
        {
            // line is "realm somename"
            if( strncmp(line, "realm", strlen("realm")) != 0 )
            {
                    qtss_fprintf(stderr, "Invalid users file.\n");
                    qtss_fprintf(stderr, "The first non-comment non-blank line must be the realm line\n");
                    qtss_fprintf(stderr, "The file may have been tampered manually!\n");				
					CleanupAndExit();
            }
            strcpy(realmFromFile ,line + strlen("realm")+1); 
            PutLine(tempUsersFilePtr, line);
            break;  
        }
    }
    // Look for an existing entry with the username
    found = 0;
    while (!(GetLine(line, MAX_LINE_LEN, usersFilePtr))) 
    {
        //write comments and blank lines out to temp file
        if (found || (line[0] == '#') || (line[0] == 0)) 
        {
            PutLine(tempUsersFilePtr, line);
            continue;
        }
        strcpy(lineFromFile, line);
        GetWord(usernameFromFile, lineFromFile, ':');

        //if not the user we're looking for, write the line out to the temp file
        if (strcmp(userName, usernameFromFile) != 0) 
        {
            PutLine(tempUsersFilePtr, line);
            continue;
        }
        else 
        {
            if (doDeleteUser)
            {   //to delete a user - just don't write it out to the temp file
                qtss_printf("Deleting user %s\n", userName);
				//delete user from all groups in the group file
				qtss_printf("Deleting user %s from all groups\n", userName);
				AddOrDeleteUserFromGroup(0, userName, NULL, qtgroupsFilePath, tempGroupsFile);
				
            }
            else
            {
				if (addUserToGroup)
				{
					PutLine(tempUsersFilePtr, line);
					
					qtss_printf("Adding user %s to group %s\n", userName, groupName);
					AddOrDeleteUserFromGroup(1, userName, groupName, qtgroupsFilePath, tempGroupsFile);
				}
				else if (deleteUserFromGroup)
				{
					PutLine(tempUsersFilePtr, line);
					
					qtss_printf("Deleting user %s from group %s\n", userName, groupName);
					AddOrDeleteUserFromGroup(0, userName, groupName, qtgroupsFilePath, tempGroupsFile);
				}
				else
				{
					qtss_printf("Changing password for user %s\n", userName);
					if(password != NULL)
						AddPasswordWithoutPrompt(userName, password, realmFromFile, tempUsersFilePtr);
					else 
						AddPassword(userName, realmFromFile, tempUsersFilePtr);
				}
            }
            found = 1;
        }
    }
    
    if (!found) 
    {
        if (doDeleteUser)
        {
            qtss_printf("Username %s not found in users file.\n", userName);
			
			//delete user from all groups in the group file
			qtss_printf("Deleting user %s from all groups if found in groups file\n", userName);
			AddOrDeleteUserFromGroup(0, userName, NULL, qtgroupsFilePath, tempGroupsFile);
			CleanupAndExit();
        }

        /* check for : in name before adding user */
        if(strchr(userName, ':') != NULL) 
        {
            qtss_printf("Username cannot contain a ':' character.");
			CleanupAndExit();
        }
    
        qtss_printf("Adding userName %s\n", userName);
        if(password != NULL)
            AddPasswordWithoutPrompt(userName, password, realmFromFile, tempUsersFilePtr);
        else 
            AddPassword(userName, realmFromFile, tempUsersFilePtr);
			
		if (addUserToGroup)
		{
			qtss_printf("Adding user %s to group %s\n", userName, groupName);
			AddOrDeleteUserFromGroup(1, userName, groupName, qtgroupsFilePath, tempGroupsFile);
		}
		else if (deleteUserFromGroup)
		{
			qtss_printf("Deleting user %s from group %s\n", userName, groupName);
			AddOrDeleteUserFromGroup(0, userName, groupName, qtgroupsFilePath, tempGroupsFile);
		}
    }
    	
    fclose(usersFilePtr);
    fclose(tempUsersFilePtr);
    
    // Remove old file and change name of temp file to match new file
    remove(qtusersFilePath);
    
    result = rename(tempUsersFile, qtusersFilePath);
    if(result != 0)
	{
        perror("rename failed with error");
		CleanupAndExit();
	}
	SetPrivileges(qtusersFilePath);

    return 0;
}
static void AddOrDeleteUserFromGroup(int add, char *userName, char *groupName, char *inGroupsFilePath, char *inTempGroupsFilePath)
{
    char line[MAX_LINE_LEN];
    char lineFromFile[MAX_LINE_LEN];
    char groupNameFromFile[MAX_STRING_LEN + 1];
    bool foundGroup = false;
	char userInGroup[MAX_STRING_LEN + 1];
	bool addedUserToGroup = false;
	FILE *groupsFilePtr, *tempGroupsFilePtr;

    if (!(groupsFilePtr = fopen(inGroupsFilePath, "r")))
    {   
		if (add)
		{
			char buffer[kErrorStrSize];
			qtss_fprintf(stderr, "Could not open groups file %s for reading. (err=%d:%s)\n", inGroupsFilePath, errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
			CleanupAndExit();
		}
		else
			return;
    }
		
	if (!(tempGroupsFilePtr = fopen(inTempGroupsFilePath, "w"))) 
    {   
        char buffer[kErrorStrSize];
        qtss_fprintf(stderr, "Could not open temp groups file. (err=%d %s)\n", errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
		CleanupAndExit();
    }
	
	while (!(GetLine(line, MAX_LINE_LEN, groupsFilePtr))) 
    {
        //write comments and blank lines out to temp file
        if (foundGroup || (line[0] == '#') || (line[0] == 0)) 
        {
            PutLine(tempGroupsFilePtr, line);
            continue;
        }
		
        strcpy(lineFromFile, line);
		EatWhitespace(lineFromFile);
        GetWord(groupNameFromFile, lineFromFile, ':');

        //if it's not the group we're looking for, write the line out to the temp file
        if ((groupName != NULL) && strcmp(groupName, groupNameFromFile) != 0) 
        {
            PutLine(tempGroupsFilePtr, line);
            continue;
        }
        else 
        {
			PutWord(tempGroupsFilePtr, groupNameFromFile, ':');
			
			while (true)
			{
				userInGroup[0] = '\0';
				EatWhitespace(lineFromFile);
				GetWord(userInGroup, lineFromFile, ' ');
				
				if (userInGroup[0] == '\0')
					break;
					
				if (strcmp(userName, userInGroup) != 0)
					PutWord(tempGroupsFilePtr, userInGroup, ' ');
				else if(add)
				{
					PutWord(tempGroupsFilePtr, userInGroup, ' ');
					addedUserToGroup = true;
				}
			}
			
			if (add && !addedUserToGroup)
			{
				PutWord(tempGroupsFilePtr, userName, ' ');
				addedUserToGroup = true;
			}
			
			fputc('\n', tempGroupsFilePtr);
				
            if (groupName != NULL)
				foundGroup = true;
        }
    }
	
	if (add && !addedUserToGroup)
	{
		PutWord(tempGroupsFilePtr, groupName, ':');
		PutLine(tempGroupsFilePtr, userName);
	}
	
	fclose(tempGroupsFilePtr);
	fclose(groupsFilePtr);
	
    // Rename the temp groups file to the groups file
    //remove(qtusersFilePath);
    
    if (rename(inTempGroupsFilePath, inGroupsFilePath) != 0)
	{
        perror("rename failed with error");
		CleanupAndExit();
	}
	
	delete [] inTempGroupsFilePath;
	SetPrivileges(inGroupsFilePath);

}