summaryrefslogtreecommitdiffstats
path: root/winsup/cygserver/pwdgrp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygserver/pwdgrp.cc')
-rw-r--r--winsup/cygserver/pwdgrp.cc161
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__ */