170 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| /* pwdgrp.cc: Request account information
 | |
| 
 | |
|    Copyright 2014, 2015 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;
 | |
|     default:
 | |
|       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 ?: "") + 1);
 | |
|   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;
 | |
| 	default:
 | |
| 	  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;
 | |
|     default:
 | |
|       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) + 1);
 | |
|   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;
 | |
| 	default:
 | |
| 	  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__ */
 |