(lsa_open_policy): Declare. (lsa_close_policy): Declare. * sec_auth.cc (lsa_open_policy): Rename from open_local_policy. Take server name as parameter. Return NULL in case of error, rather than INVALID_HANDLE_VALUE. (lsa_close_policy): Rename from close_local_policy. Make externally available. Get handle by value. (create_token): Convert call to open_local_policy/close_local_policy according to aforementioned changes. (lsaauth): Ditto. (lsaprivkeyauth): Ditto. * setlsapwd.cc (setlsapwd): Ditto.
		
			
				
	
	
		
			103 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* setlsapwd.cc: Set LSA private data password for current user.
 | 
						|
 | 
						|
   Copyright 2008, 2009, 2011, 2014 Red Hat, Inc.
 | 
						|
 | 
						|
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 "pwdgrp.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 = INVALID_HANDLE_VALUE;
 | 
						|
  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, false);
 | 
						|
 | 
						|
      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)
 | 
						|
	{
 | 
						|
	  memset (data.Buffer, 0, data.Length);
 | 
						|
	  free (data_buf);
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return ret;
 | 
						|
}
 |