* Makefile.in (OBJS): Add setpwd.o.

* README: Explain new service to store passwords in the LSA registry
	area.
	* bsd_helper.cc (get_token_info): Make externally available.
	* bsd_helper.h (get_token_info): Declare.
	* client.cc (client_request::handle_request): Add case for
	CYGSERVER_REQUEST_SETPWD request.
	* setpwd.cc: New file implementing the CYGSERVER_REQUEST_SETPWD
	request.
This commit is contained in:
Corinna Vinschen 2008-11-26 10:18:53 +00:00
parent 51303cbd0c
commit d4db08d7a6
7 changed files with 125 additions and 2 deletions

View File

@ -1,3 +1,15 @@
2008-11-26 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (OBJS): Add setpwd.o.
* README: Explain new service to store passwords in the LSA registry
area.
* bsd_helper.cc (get_token_info): Make externally available.
* bsd_helper.h (get_token_info): Declare.
* client.cc (client_request::handle_request): Add case for
CYGSERVER_REQUEST_SETPWD request.
* setpwd.cc: New file implementing the CYGSERVER_REQUEST_SETPWD
request.
2008-10-30 Christopher Faylor <me+cygwin@cgf.cx>
* Makefile.in: Use -static-libgcc when creating cygserver.exe.

View File

@ -41,7 +41,7 @@ override CXXFLAGS+=-MMD -DHAVE_DECL_GETOPT=0 -D__OUTSIDE_CYGWIN__ -DSYSCONFDIR="
OBJS:= cygserver.o client.o process.o msg.o sem.o shm.o threaded_queue.o \
transport.o transport_pipes.o \
bsd_helper.o bsd_log.o bsd_mutex.o \
sysv_msg.o sysv_sem.o sysv_shm.o
sysv_msg.o sysv_sem.o sysv_shm.o setpwd.o
LIBOBJS:=${patsubst %.o,lib%.o,$(OBJS)}
CYGWIN_OBJS:=$(cygwin_build)/version.o

View File

@ -12,6 +12,12 @@ What is Cygserver?
- XSI IPC Message Queues.
- XSI IPC Semaphores.
- XSI IPC Shared Memory.
- Allows non-privileged users to store obfuscated passwords in the
registry to be used for setuid(2) to create user tokens with network
credentials. This service is used by `passwd -R'. Using the stored
passwords in setuid(2) does not require running cygserver. The
registry storage is the same as Windows uses to store passwords for
accounts running Windows services.
Cygserver command line options:

View File

@ -308,7 +308,7 @@ is_grp_member (gid_t grp, gid_t *grplist, int listsize)
* This function mallocs the necessary buffer spcae by itself. It
* must be free'd by the calling function.
*/
static void *
void *
get_token_info (HANDLE tok, TOKEN_INFORMATION_CLASS tic)
{
void *buf;

View File

@ -44,6 +44,7 @@ int win_copyout (struct thread *, const void *, void *, size_t);
#define copyin(a,b,c) win_copyin((td),(a),(b),(c))
#define copyout(a,b,c) win_copyout((td),(a),(b),(c))
void *get_token_info (HANDLE, TOKEN_INFORMATION_CLASS);
int ipcperm (struct thread *, struct ipc_perm *, unsigned int);
int suser (struct thread *);
bool adjust_identity_info (struct proc *p);

View File

@ -27,6 +27,7 @@ details. */
#include "cygserver_msg.h"
#include "cygserver_sem.h"
#include "cygserver_shm.h"
#include "cygserver_setpwd.h"
#include "cygserver.h"
#include "transport.h"
@ -293,6 +294,9 @@ client_request::handle_request (transport_layer_base *const conn,
case CYGSERVER_REQUEST_SHM:
req = new client_request_shm;
break;
case CYGSERVER_REQUEST_SETPWD:
req = new client_request_setpwd;
break;
default:
syscall_printf ("unknown request code %d received: request ignored",
header.request_code);

100
winsup/cygserver/setpwd.cc Normal file
View File

@ -0,0 +1,100 @@
/* setpwd.cc: Set LSA private data password for current user.
Copyright 2008 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. */
#ifdef __OUTSIDE_CYGWIN__
#include "woutsup.h"
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <wchar.h>
#include <ntsecapi.h>
#include <ntdef.h>
#include "ntdll.h"
#include "cygserver.h"
#include "process.h"
#include "transport.h"
#include "cygserver_setpwd.h"
client_request_setpwd::client_request_setpwd ()
: client_request (CYGSERVER_REQUEST_SETPWD,
&_parameters, sizeof (_parameters))
{
}
void
client_request_setpwd::serve (transport_layer_base *const conn,
process_cache *const cache)
{
HANDLE tok;
PTOKEN_USER user;
WCHAR sidbuf[128], key_name [128 + wcslen (CYGWIN_LSA_KEY_PREFIX)];
UNICODE_STRING sid, key, data;
syscall_printf ("Request to set private data");
if (msglen () != sizeof (_parameters.in))
{
syscall_printf ("bad request body length: expecting %lu bytes, got %lu",
sizeof (_parameters), msglen ());
error_code (EINVAL);
msglen (0);
return;
}
msglen (0);
if (!conn->impersonate_client ())
{
error_code (EACCES);
return;
}
if (!OpenThreadToken (GetCurrentThread (), TOKEN_READ, TRUE, &tok))
{
conn->revert_to_self ();
error_code (EACCES);
return;
}
/* Get uid from user SID in token. */
user = (PTOKEN_USER) get_token_info (tok, TokenUser);
CloseHandle (tok);
conn->revert_to_self ();
if (!user)
{
error_code (EACCES);
return;
}
LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
HANDLE lsa;
NTSTATUS status = LsaOpenPolicy (NULL, &oa, POLICY_CREATE_SECRET, &lsa);
if (!NT_SUCCESS (status))
{
error_code (LsaNtStatusToWinError (status));
return;
}
RtlInitEmptyUnicodeString (&sid, sidbuf, sizeof sidbuf);
RtlConvertSidToUnicodeString (&sid, user->User.Sid, FALSE);
free (user);
RtlInitEmptyUnicodeString (&key, key_name, sizeof key_name);
RtlAppendUnicodeToString (&key, CYGWIN_LSA_KEY_PREFIX);
RtlAppendUnicodeStringToString (&key, &sid);
RtlInitUnicodeString (&data, _parameters.in.passwd);
status = LsaStorePrivateData (lsa, &key, data.Length ? &data : NULL);
if (NT_SUCCESS (status))
error_code (0);
else
error_code (LsaNtStatusToWinError (status));
syscall_printf ("Request to set private data returns error %d", error_code ());
LsaClose (lsa);
}
#endif /* __OUTSIDE_CYGWIN__ */