Bump GPLv2+ to GPLv3+ for some files, clarify BSD 2-clause. Everything else stays under GPLv3+. New Linking Exception exempts resulting executables from LGPLv3 section 4. Add CONTRIBUTORS file to keep track of licensing. Remove 'Copyright Red Hat Inc' comments. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* setlsapwd.cc: Set LSA private data password for current user.
 | 
						|
 | 
						|
This file is part of Cygwin.
 | 
						|
 | 
						|
This software is a copyrighted work licensed under the terms of the
 | 
						|
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | 
						|
details. */
 | 
						|
 | 
						|
#include "winsup.h"
 | 
						|
#include "shared_info.h"
 | 
						|
#include "cygerrno.h"
 | 
						|
#include "path.h"
 | 
						|
#include "fhandler.h"
 | 
						|
#include "dtable.h"
 | 
						|
#include "cygheap.h"
 | 
						|
#include "security.h"
 | 
						|
#include "cygserver_setpwd.h"
 | 
						|
#include "ntdll.h"
 | 
						|
#include <ntsecapi.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <wchar.h>
 | 
						|
 | 
						|
/*
 | 
						|
 * client_request_setpwd Constructor
 | 
						|
 */
 | 
						|
 | 
						|
client_request_setpwd::client_request_setpwd (PUNICODE_STRING passwd)
 | 
						|
  : client_request (CYGSERVER_REQUEST_SETPWD, &_parameters, sizeof (_parameters))
 | 
						|
{
 | 
						|
  memset (_parameters.in.passwd, 0, sizeof _parameters.in.passwd);
 | 
						|
  if (passwd->Length > 0 && passwd->Length < 256 * sizeof (WCHAR))
 | 
						|
    wcpncpy (_parameters.in.passwd, passwd->Buffer, 255);
 | 
						|
 | 
						|
  msglen (sizeof (_parameters.in));
 | 
						|
}
 | 
						|
 | 
						|
unsigned long
 | 
						|
setlsapwd (const char *passwd, const char *username)
 | 
						|
{
 | 
						|
  unsigned long ret = (unsigned long) -1;
 | 
						|
  HANDLE lsa;
 | 
						|
  WCHAR sid[128];
 | 
						|
  WCHAR key_name[128 + wcslen (CYGWIN_LSA_KEY_PREFIX)];
 | 
						|
  PWCHAR data_buf = NULL;
 | 
						|
  UNICODE_STRING key;
 | 
						|
  UNICODE_STRING data;
 | 
						|
 | 
						|
  if (username)
 | 
						|
    {
 | 
						|
      cygsid psid;
 | 
						|
      struct passwd *pw = internal_getpwnam (username);
 | 
						|
 | 
						|
      if (!pw || !psid.getfrompw (pw))
 | 
						|
	{
 | 
						|
	  set_errno (ENOENT);
 | 
						|
	  return ret;
 | 
						|
	}
 | 
						|
      wcpcpy (wcpcpy (key_name, CYGWIN_LSA_KEY_PREFIX), psid.string (sid));
 | 
						|
    }
 | 
						|
  else
 | 
						|
    wcpcpy (wcpcpy (key_name, CYGWIN_LSA_KEY_PREFIX),
 | 
						|
	    cygheap->user.get_windows_id (sid));
 | 
						|
  RtlInitUnicodeString (&key, key_name);
 | 
						|
  if (!passwd || ! *passwd
 | 
						|
      || sys_mbstowcs_alloc (&data_buf, HEAP_NOTHEAP, passwd))
 | 
						|
    {
 | 
						|
      memset (&data, 0, sizeof data);
 | 
						|
      if (data_buf)
 | 
						|
	RtlInitUnicodeString (&data, data_buf);
 | 
						|
      /* First try it locally.  Works for admin accounts. */
 | 
						|
      if ((lsa = lsa_open_policy (NULL, POLICY_CREATE_SECRET)))
 | 
						|
	{
 | 
						|
	  NTSTATUS status = LsaStorePrivateData (lsa, &key,
 | 
						|
						 data.Length ? &data : NULL);
 | 
						|
	  /* Success or we're trying to remove a password entry which doesn't
 | 
						|
	     exist. */
 | 
						|
	  if (NT_SUCCESS (status)
 | 
						|
	      || (data.Length == 0 && status == STATUS_OBJECT_NAME_NOT_FOUND))
 | 
						|
	    ret = 0;
 | 
						|
	  else
 | 
						|
	    __seterrno_from_nt_status (status);
 | 
						|
	  lsa_close_policy (lsa);
 | 
						|
	}
 | 
						|
      else if (ret && !username)
 | 
						|
	{
 | 
						|
	  client_request_setpwd request (&data);
 | 
						|
	  if (request.make_request () == -1 || request.error_code ())
 | 
						|
	    set_errno (request.error_code ());
 | 
						|
	  else
 | 
						|
	    ret = 0;
 | 
						|
	}
 | 
						|
      if (data_buf)
 | 
						|
	{
 | 
						|
	  RtlSecureZeroMemory (data.Buffer, data.Length);
 | 
						|
	  free (data_buf);
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return ret;
 | 
						|
}
 |