diff options
Diffstat (limited to 'winsup/cygserver/pwdgrp.cc')
-rw-r--r-- | winsup/cygserver/pwdgrp.cc | 161 |
1 files changed, 161 insertions, 0 deletions
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 <stdio.h> +#include <errno.h> +#include <pwd.h> +#include <grp.h> +#include <sys/cygwin.h> + +#include "cygserver.h" +#include "process.h" +#include "transport.h" + +#include "cygserver_pwdgrp.h" + +#include <sddl.h> + +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__ */ |