/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you 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.
 */

#include "winutils.h"

//----------------------------------------------------------------------------
// Function: ChangeFileOwnerBySid
//
// Description:
//  Change a file or directory ownership by giving new owner and group SIDs
//
// Returns:
//  ERROR_SUCCESS: on success
//  Error code: otherwise
//
// Notes:
//  This function is long path safe, i.e. the path will be converted to long
//  path format if not already converted. So the caller does not need to do
//  the converstion before calling the method.
//
static DWORD ChangeFileOwnerBySid(__in LPCWSTR path,
  __in_opt PSID pNewOwnerSid, __in_opt PSID pNewGroupSid)
{
  LPWSTR longPathName = NULL;
  INT oldMode = 0;

  SECURITY_INFORMATION securityInformation = 0;

  DWORD dwRtnCode = ERROR_SUCCESS;

  // Convert the path the the long path
  //
  dwRtnCode = ConvertToLongPath(path, &longPathName);
  if (dwRtnCode != ERROR_SUCCESS)
  {
    goto ChangeFileOwnerByNameEnd;
  }

  // Get a pointer to the existing owner information and DACL
  //
  dwRtnCode = FindFileOwnerAndPermission(longPathName, NULL, NULL, &oldMode);
  if (dwRtnCode != ERROR_SUCCESS)
  {
    goto ChangeFileOwnerByNameEnd;
  }

  // We need SeTakeOwnershipPrivilege to set the owner if the caller does not
  // have WRITE_OWNER access to the object; we need SeRestorePrivilege if the
  // SID is not contained in the caller's token, and have the SE_GROUP_OWNER
  // permission enabled.
  //
  if (!EnablePrivilege(L"SeTakeOwnershipPrivilege"))
  {
    fwprintf(stdout, L"INFO: The user does not have SeTakeOwnershipPrivilege.\n");
  }
  if (!EnablePrivilege(L"SeRestorePrivilege"))
  {
    fwprintf(stdout, L"INFO: The user does not have SeRestorePrivilege.\n");
  }

  assert(pNewOwnerSid != NULL || pNewGroupSid != NULL);

  // Set the owners of the file.
  //
  if (pNewOwnerSid != NULL) securityInformation |= OWNER_SECURITY_INFORMATION;
  if (pNewGroupSid != NULL) securityInformation |= GROUP_SECURITY_INFORMATION;
  dwRtnCode = SetNamedSecurityInfoW(
    longPathName,
    SE_FILE_OBJECT,
    securityInformation,
    pNewOwnerSid,
    pNewGroupSid,
    NULL,
    NULL);
  if (dwRtnCode != ERROR_SUCCESS)
  {
    goto ChangeFileOwnerByNameEnd;
  }

  // Set the permission on the file for the new owner.
  //
  dwRtnCode = ChangeFileModeByMask(longPathName, oldMode);
  if (dwRtnCode != ERROR_SUCCESS)
  {
    goto ChangeFileOwnerByNameEnd;
  }

ChangeFileOwnerByNameEnd:
  LocalFree(longPathName);
  return dwRtnCode;
}

//----------------------------------------------------------------------------
// Function: Chown
//
// Description:
//	The main method for chown command
//
// Returns:
//	0: on success
//
// Notes:
//
//
int Chown(__in int argc, __in_ecount(argc) wchar_t *argv[])
{
  LPWSTR pathName = NULL;

  LPWSTR ownerInfo = NULL;

  WCHAR const * colonPos = NULL;

  LPWSTR userName = NULL;
  size_t userNameLen = 0;

  LPWSTR groupName = NULL;
  size_t groupNameLen = 0;

  PSID pNewOwnerSid = NULL;
  PSID pNewGroupSid = NULL;

  DWORD dwRtnCode = 0;

  int ret = EXIT_FAILURE;

  if (argc >= 3)
  {
    ownerInfo = argv[1];
    pathName = argv[2];
  }
  else
  {
    fwprintf(stderr, L"Incorrect command line arguments.\n\n");
    ChownUsage(argv[0]);
    return ret;
  }

  // Parsing the owner name
  //
  if ((colonPos = wcschr(ownerInfo, L':')) != NULL)
  {
    if (colonPos - ownerInfo != 0)
    {
      // Length includes NULL terminator
      userNameLen = colonPos - ownerInfo + 1;
      userName = (LPTSTR)LocalAlloc(LPTR, userNameLen * sizeof(WCHAR));
      if (userName == NULL)
      {
        ReportErrorCode(L"LocalAlloc", GetLastError());
        goto ChownEnd;
      }
      if (FAILED(StringCchCopyNW(userName, userNameLen,
        ownerInfo, userNameLen - 1)))
        goto ChownEnd;
    }

    if (*(colonPos + 1) != 0)
    {
      // Length includes NULL terminator
      groupNameLen = wcslen(ownerInfo) - (colonPos - ownerInfo) + 1;
      groupName = (LPTSTR)LocalAlloc(LPTR, groupNameLen * sizeof(WCHAR));
      if (groupName == NULL)
      {
        ReportErrorCode(L"LocalAlloc", GetLastError());
        goto ChownEnd;
      }
      if (FAILED(StringCchCopyNW(groupName, groupNameLen,
        colonPos + 1, groupNameLen)))
        goto ChownEnd;
    }
  }
  else
  {
    // Length includes NULL terminator
    userNameLen = wcslen(ownerInfo) + 1;
    userName = (LPWSTR)LocalAlloc(LPTR, userNameLen * sizeof(WCHAR));
    if (userName == NULL)
    {
      ReportErrorCode(L"LocalAlloc", GetLastError());
      goto ChownEnd;
    }
    if (FAILED(StringCchCopyNW(userName, userNameLen, ownerInfo, userNameLen)))
      goto ChownEnd;
  }

  // Not allow zero length user name or group name in the parsing results.
  //
  assert(userName == NULL || wcslen(userName) > 0);
  assert(groupName == NULL || wcslen(groupName) > 0);

  // Nothing to change if both names are empty
  //
  if ((userName == NULL) && (groupName == NULL))
  {
    ret = EXIT_SUCCESS;
    goto ChownEnd;
  }

  if (userName != NULL)
  {
    dwRtnCode = GetSidFromAcctNameW(userName, &pNewOwnerSid);
    if (dwRtnCode != ERROR_SUCCESS)
    {
      ReportErrorCode(L"GetSidFromAcctName", dwRtnCode);
      fwprintf(stderr, L"Invalid user name: %s\n", userName);
      goto ChownEnd;
    }
  }

  if (groupName != NULL)
  {
    dwRtnCode = GetSidFromAcctNameW(groupName, &pNewGroupSid);
    if (dwRtnCode != ERROR_SUCCESS)
    {
      ReportErrorCode(L"GetSidFromAcctName", dwRtnCode);
      fwprintf(stderr, L"Invalid group name: %s\n", groupName);
      goto ChownEnd;
    }
  }

  if (wcslen(pathName) == 0 || wcsspn(pathName, L"/?|><:*\"") != 0)
  {
    fwprintf(stderr, L"Incorrect file name format: %s\n", pathName);
    goto ChownEnd;
  }

  dwRtnCode = ChangeFileOwnerBySid(pathName, pNewOwnerSid, pNewGroupSid);
  if (dwRtnCode != ERROR_SUCCESS)
  {
    ReportErrorCode(L"ChangeFileOwnerBySid", dwRtnCode);
    goto ChownEnd;
  }

  ret = EXIT_SUCCESS;

ChownEnd:
  LocalFree(userName);
  LocalFree(groupName);
  LocalFree(pNewOwnerSid);
  LocalFree(pNewGroupSid);

  return ret;
}

void ChownUsage(LPCWSTR program)
{
  fwprintf(stdout, L"\
Usage: %s [OWNER][:[GROUP]] [FILE]\n\
Change the owner and/or group of the FILE to OWNER and/or GROUP.\n\
\n\
Note:\n\
On Linux, if a colon but no group name follows the user name, the group of\n\
the files is changed to that user\'s login group. Windows has no concept of\n\
a user's login group. So we do not change the group owner in this case.\n",
program);
}
