From 600afd99abacfd836b41930c6bc5e014bc5d94e3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 12 Mar 2014 17:37:04 +0000 Subject: [PATCH] * Makefile.in (OBJS): Add pwdgrp.o. * client.cc (client_request::handle_request): Handle CYGSERVER_REQUEST_PWDGRP message. * pwdgrp.cc: New file implementing CYGSERVER_REQUEST_PWDGRP. --- winsup/cygserver/ChangeLog | 7 ++ winsup/cygserver/Makefile.in | 4 +- winsup/cygserver/client.cc | 4 + winsup/cygserver/pwdgrp.cc | 161 +++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 winsup/cygserver/pwdgrp.cc diff --git a/winsup/cygserver/ChangeLog b/winsup/cygserver/ChangeLog index f0a9911a7..b45148355 100644 --- a/winsup/cygserver/ChangeLog +++ b/winsup/cygserver/ChangeLog @@ -1,3 +1,10 @@ +2014-03-12 Corinna Vinschen + + * Makefile.in (OBJS): Add pwdgrp.o. + * client.cc (client_request::handle_request): Handle + CYGSERVER_REQUEST_PWDGRP message. + * pwdgrp.cc: New file implementing CYGSERVER_REQUEST_PWDGRP. + 2014-03-12 Corinna Vinschen * Throughout, fix format specifiers in debug statements to accommodate diff --git a/winsup/cygserver/Makefile.in b/winsup/cygserver/Makefile.in index e2fe30992..816f5b3db 100644 --- a/winsup/cygserver/Makefile.in +++ b/winsup/cygserver/Makefile.in @@ -1,5 +1,5 @@ # Makefile for Cygwin server -# Copyright 2003, 2006, 2007, 2008, 2009 Red Hat, Inc. +# Copyright 2003, 2006, 2007, 2008, 2009, 2014 Red Hat, Inc. # This file is part of Cygwin. @@ -46,7 +46,7 @@ AR:=@AR@ 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 setpwd.o + sysv_msg.o sysv_sem.o sysv_shm.o setpwd.o pwdgrp.o LIBOBJS:=${patsubst %.o,lib%.o,$(OBJS)} CYGWIN_OBJS:=$(cygwin_build)/version.o diff --git a/winsup/cygserver/client.cc b/winsup/cygserver/client.cc index 94e56f383..9775bbc44 100644 --- a/winsup/cygserver/client.cc +++ b/winsup/cygserver/client.cc @@ -26,6 +26,7 @@ details. */ #include "cygserver_sem.h" #include "cygserver_shm.h" #include "cygserver_setpwd.h" +#include "cygserver_pwdgrp.h" #include "cygserver.h" #include "transport.h" @@ -285,6 +286,9 @@ client_request::handle_request (transport_layer_base *const conn, case CYGSERVER_REQUEST_SETPWD: req = new client_request_setpwd; break; + case CYGSERVER_REQUEST_PWDGRP: + req = new client_request_pwdgrp; + break; default: syscall_printf ("unknown request code %d received: request ignored", header.request_code); diff --git a/winsup/cygserver/pwdgrp.cc b/winsup/cygserver/pwdgrp.cc new file mode 100644 index 000000000..90e88ce58 --- /dev/null +++ b/winsup/cygserver/pwdgrp.cc @@ -0,0 +1,161 @@ +/* pwdgrp.cc: Request account information + + Copyright 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. */ + +#ifdef __OUTSIDE_CYGWIN__ +#include "woutsup.h" + +#include +#include +#include +#include +#include + +#include "cygserver.h" +#include "process.h" +#include "transport.h" + +#include "cygserver_pwdgrp.h" + +#include + +client_request_pwdgrp::client_request_pwdgrp () + : client_request (CYGSERVER_REQUEST_PWDGRP, + &_parameters, sizeof (_parameters)) +{ +} + +void +client_request_pwdgrp::pwd_serve () +{ + struct passwd *pwd = NULL; + + switch (_parameters.in.type) + { + case SID_arg: + pwd = (struct passwd *) cygwin_internal (CW_GETPWSID, 0, + &_parameters.in.arg.sid); + break; + case NAME_arg: + pwd = getpwnam (_parameters.in.arg.name); + break; + case ID_arg: + pwd = getpwuid (_parameters.in.arg.id); + break; + } + if (pwd) + msglen (snprintf (_parameters.out.line, sizeof _parameters.out.line, + "%s:%s:%u:%u:%s:%s:%s", + pwd->pw_name ?: "", + pwd->pw_passwd ?: "", + (uint32_t) pwd->pw_uid, + (uint32_t) pwd->pw_gid, + pwd->pw_gecos ?: "", + pwd->pw_dir ?: "", + pwd->pw_shell ?: "")); + else + { + switch (_parameters.in.type) + { + case SID_arg: + { + char *str; + if (ConvertSidToStringSid (&_parameters.in.arg.sid, &str)) + { + debug_printf ("User <%s> failed", str); + LocalFree (str); + } + } + break; + case NAME_arg: + debug_printf ("User <%s> failed", _parameters.in.arg.name); + break; + case ID_arg: + debug_printf ("User <%u> failed", _parameters.in.arg.id); + break; + } + _parameters.out.line[0] = '\0'; + msglen (0); + error_code (ENOENT); + } +} + +void +client_request_pwdgrp::grp_serve () +{ + struct group *grp = NULL; + + switch (_parameters.in.type) + { + case SID_arg: + grp = (struct group *) cygwin_internal (CW_GETGRSID, 0, + &_parameters.in.arg.sid); + break; + case NAME_arg: + grp = getgrnam (_parameters.in.arg.name); + break; + case ID_arg: + grp = getgrgid (_parameters.in.arg.id); + break; + } + if (grp) + msglen (snprintf (_parameters.out.line, sizeof _parameters.out.line, + "%s:%s:%u:", + grp->gr_name ?: "", + grp->gr_passwd ?: "", + (uint32_t) grp->gr_gid)); + else + { + switch (_parameters.in.type) + { + case SID_arg: + { + char *str; + if (ConvertSidToStringSid (&_parameters.in.arg.sid, &str)) + { + debug_printf ("Group <%s> failed", str); + LocalFree (str); + } + } + break; + case NAME_arg: + debug_printf ("Group <%s> failed", _parameters.in.arg.name); + break; + case ID_arg: + debug_printf ("Group <%u> failed", _parameters.in.arg.id); + break; + } + _parameters.out.line[0] = '\0'; + msglen (0); + error_code (ENOENT); + } +} + +void +client_request_pwdgrp::serve (transport_layer_base *const conn, + process_cache *const cache) +{ + debug_printf ("Request account information"); + if (msglen () < __builtin_offsetof (struct _pwdgrp_param_t::_pwdgrp_in_t, arg) + + sizeof (uint32_t) + || msglen () > sizeof (_parameters.in)) + { + syscall_printf ("bad request body length: got %lu", msglen ()); + error_code (EINVAL); + msglen (0); + return; + } + error_code (0); + if (_parameters.in.group) + grp_serve (); + else + pwd_serve (); + debug_printf ("Request account information returns <%s> error %d", _parameters.out.line, error_code ()); +} +#endif /* __OUTSIDE_CYGWIN__ */