276 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			276 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* pwdgrp.h
 | |
| 
 | |
|    Stuff common to pwd and grp handling.
 | |
| 
 | |
| 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. */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include "sync.h"
 | |
| #include "ldap.h"
 | |
| #include "miscfuncs.h"
 | |
| #include "userinfo.h"
 | |
| 
 | |
| /* These functions are needed to allow searching and walking through
 | |
|    the passwd and group lists */
 | |
| extern struct passwd *internal_getpwsid (cygpsid &, cyg_ldap * = NULL);
 | |
| extern struct passwd *internal_getpwsid_from_db (cygpsid &sid);
 | |
| extern struct passwd *internal_getpwnam (const char *, cyg_ldap * = NULL);
 | |
| extern struct passwd *internal_getpwuid (uid_t, cyg_ldap * = NULL);
 | |
| extern struct group *internal_getgrsid (cygpsid &, cyg_ldap * = NULL);
 | |
| extern struct group *internal_getgrsid_from_db (cygpsid &sid);
 | |
| extern struct group *internal_getgrgid (gid_t, cyg_ldap * = NULL);
 | |
| extern struct group *internal_getgrnam (const char *, cyg_ldap * = NULL);
 | |
| 
 | |
| extern int internal_getgroups (int, gid_t *, cyg_ldap *);
 | |
| 
 | |
| /* These functions are called from mkpasswd/mkgroup via cygwin_internal. */
 | |
| void *setpwent_filtered (int enums, PCWSTR enum_tdoms);
 | |
| void *getpwent_filtered (void *gr);
 | |
| void endpwent_filtered (void *gr);
 | |
| void *setgrent_filtered (int enums, PCWSTR enum_tdoms);
 | |
| void *getgrent_filtered (void *gr);
 | |
| void endgrent_filtered (void *gr);
 | |
| 
 | |
| /* NOTE: The below sid members were cygsid's originally.  Don't do that.
 | |
|    cygsid's are pointer based.  When adding new entries to the passwd or
 | |
|    group caches, a crealloc call potenitally moves the entries and then
 | |
|    the cygsid pointers point into neverneverland. */
 | |
| struct pg_pwd
 | |
| {
 | |
|   struct passwd p;
 | |
|   BYTE sid[SECURITY_MAX_SID_SIZE];
 | |
|   size_t len;
 | |
| };
 | |
| 
 | |
| struct pg_grp
 | |
| {
 | |
|   struct group g;
 | |
|   BYTE sid[SECURITY_MAX_SID_SIZE];
 | |
|   size_t len;
 | |
| };
 | |
| 
 | |
| class pwdgrp
 | |
| {
 | |
|   friend class pg_ent;
 | |
|   friend class pw_ent;
 | |
|   friend class gr_ent;
 | |
| 
 | |
|   unsigned pwdgrp_buf_elem_size;
 | |
|   void *pwdgrp_buf;
 | |
|   bool (pwdgrp::*parse) ();
 | |
|   UNICODE_STRING path;
 | |
|   OBJECT_ATTRIBUTES attr;
 | |
|   LARGE_INTEGER last_modified;
 | |
|   char *lptr;
 | |
|   ULONG curr_lines;
 | |
|   ULONG max_lines;
 | |
|   static muto pglock;
 | |
| 
 | |
|   bool parse_passwd ();
 | |
|   bool parse_group ();
 | |
|   char *add_line (char *);
 | |
|   char *raw_ptr () const {return lptr;}
 | |
|   char *next_str (char);
 | |
|   bool next_num (unsigned long&);
 | |
|   bool next_num (unsigned int& i)
 | |
|   {
 | |
|     unsigned long x;
 | |
|     bool res = next_num (x);
 | |
|     i = (unsigned int) x;
 | |
|     return res;
 | |
|   }
 | |
|   inline bool next_num (int& i)
 | |
|   {
 | |
|     unsigned long x;
 | |
|     bool res = next_num (x);
 | |
|     i = (int) x;
 | |
|     return res;
 | |
|   }
 | |
|   void *add_account_post_fetch (char *line, bool lock);
 | |
|   void *add_account_from_file (cygpsid &sid);
 | |
|   void *add_account_from_file (const char *name);
 | |
|   void *add_account_from_file (uint32_t id);
 | |
|   void *add_account_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL);
 | |
|   void *add_account_from_windows (const char *name, cyg_ldap *pldap = NULL);
 | |
|   void *add_account_from_windows (uint32_t id, cyg_ldap *pldap = NULL);
 | |
|   void *add_account_from_cygserver (cygpsid &sid);
 | |
|   void *add_account_from_cygserver (const char *name);
 | |
|   void *add_account_from_cygserver (uint32_t id);
 | |
|   bool construct_sid_from_name (cygsid &sid, wchar_t *name, wchar_t *sep);
 | |
|   char *fetch_account_from_line (fetch_user_arg_t &arg, const char *line);
 | |
|   char *fetch_account_from_file (fetch_user_arg_t &arg);
 | |
|   char *fetch_account_from_windows (fetch_user_arg_t &arg,
 | |
| 				    cyg_ldap *pldap = NULL);
 | |
|   char *fetch_account_from_cygserver (fetch_user_arg_t &arg);
 | |
| 
 | |
| public:
 | |
|   ULONG cached_users () const { return curr_lines; }
 | |
|   ULONG cached_groups () const { return curr_lines; }
 | |
|   POBJECT_ATTRIBUTES file_attr () { return &attr; }
 | |
|   bool check_file ();
 | |
| 
 | |
|   void init_pwd ();
 | |
|   bool is_passwd () const { return pwdgrp_buf_elem_size == sizeof (pg_pwd); }
 | |
|   pg_pwd *passwd () const { return (pg_pwd *) pwdgrp_buf; };
 | |
|   struct passwd *add_user_from_cygserver (cygpsid &sid)
 | |
|     { return (struct passwd *) add_account_from_cygserver (sid); }
 | |
|   struct passwd *add_user_from_cygserver (const char *name)
 | |
|     { return (struct passwd *) add_account_from_cygserver (name); }
 | |
|   struct passwd *add_user_from_cygserver (uint32_t id)
 | |
|     { return (struct passwd *) add_account_from_cygserver (id); }
 | |
|   struct passwd *add_user_from_file (cygpsid &sid)
 | |
|     { return (struct passwd *) add_account_from_file (sid); }
 | |
|   struct passwd *add_user_from_file (const char *name)
 | |
|     { return (struct passwd *) add_account_from_file (name); }
 | |
|   struct passwd *add_user_from_file (uint32_t id)
 | |
|     { return (struct passwd *) add_account_from_file (id); }
 | |
|   struct passwd *add_user_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
 | |
|     { return (struct passwd *) add_account_from_windows (sid, pldap); }
 | |
|   struct passwd *add_user_from_windows (const char *name,
 | |
|   					cyg_ldap* pldap = NULL)
 | |
|     { return (struct passwd *) add_account_from_windows (name, pldap); }
 | |
|   struct passwd *add_user_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
 | |
|     { return (struct passwd *) add_account_from_windows (id, pldap); }
 | |
|   struct passwd *find_user (cygpsid &sid);
 | |
|   struct passwd *find_user (const char *name);
 | |
|   struct passwd *find_user (uid_t uid);
 | |
| 
 | |
|   void init_grp ();
 | |
|   bool is_group () const { return pwdgrp_buf_elem_size == sizeof (pg_grp); }
 | |
|   pg_grp *group () const { return (pg_grp *) pwdgrp_buf; };
 | |
|   struct group *add_group_from_cygserver (cygpsid &sid)
 | |
|     { return (struct group *) add_account_from_cygserver (sid); }
 | |
|   struct group *add_group_from_cygserver (const char *name)
 | |
|     { return (struct group *) add_account_from_cygserver (name); }
 | |
|   struct group *add_group_from_cygserver (uint32_t id)
 | |
|     { return (struct group *) add_account_from_cygserver (id); }
 | |
|   struct group *add_group_from_file (cygpsid &sid)
 | |
|     { return (struct group *) add_account_from_file (sid); }
 | |
|   struct group *add_group_from_file (const char *name)
 | |
|     { return (struct group *) add_account_from_file (name); }
 | |
|   struct group *add_group_from_file (uint32_t id)
 | |
|     { return (struct group *) add_account_from_file (id); }
 | |
|   struct group *add_group_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
 | |
|     { return (struct group *) add_account_from_windows (sid, pldap); }
 | |
|   struct group *add_group_from_windows (const char *name,
 | |
| 					cyg_ldap *pldap = NULL)
 | |
|     { return (struct group *) add_account_from_windows (name, pldap); }
 | |
|   struct group *add_group_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
 | |
|     { return (struct group *) add_account_from_windows (id, pldap); }
 | |
|   struct group *add_group_from_windows (fetch_acc_t &full_acc,
 | |
|   					cyg_ldap *pldap = NULL);
 | |
|   struct group *find_group (cygpsid &sid);
 | |
|   struct group *find_group (const char *name);
 | |
|   struct group *find_group (gid_t gid);
 | |
| };
 | |
| 
 | |
| class pg_ent
 | |
| {
 | |
| protected:
 | |
|   pwdgrp         pg;
 | |
|   bool           group;
 | |
|   pg_pwd         pwd;
 | |
|   pg_grp         grp;
 | |
|   NT_readline    rl;
 | |
|   cyg_ldap       cldap;
 | |
|   PCHAR          buf;
 | |
|   ULONG          cnt;
 | |
|   ULONG          max;
 | |
|   ULONG_PTR      resume;
 | |
|   int            enums;		/* ENUM_xxx values defined in sys/cygwin.h. */
 | |
|   PCWSTR         enum_tdoms;
 | |
|   bool           from_files;
 | |
|   bool           from_db;
 | |
|   UNICODE_STRING dom;
 | |
|   enum {
 | |
|     rewound = 0,
 | |
|     from_cache,
 | |
|     from_file,
 | |
|     from_builtin,
 | |
|     from_local,
 | |
|     from_sam,
 | |
|     from_ad,
 | |
|     finished
 | |
|   } state;
 | |
| 
 | |
|   void clear_cache ();
 | |
|   inline bool nss_db_enum_caches () const { return !!(enums & ENUM_CACHE); }
 | |
|   inline bool nss_db_enum_files () const { return !!(enums & ENUM_FILES); }
 | |
|   inline bool nss_db_enum_builtin () const { return !!(enums & ENUM_BUILTIN); }
 | |
|   inline bool nss_db_enum_local () const { return !!(enums & ENUM_LOCAL); }
 | |
|   inline bool nss_db_enum_primary () const { return !!(enums & ENUM_PRIMARY); }
 | |
|   inline bool nss_db_enum_tdom (PWCHAR domain)
 | |
|     {
 | |
|       if (enums & ENUM_TDOMS_ALL)
 | |
|         return true;
 | |
|       if (!(enums & ENUM_TDOMS) || !enum_tdoms || !domain)
 | |
|         return false;
 | |
|       for (PCWSTR td = enum_tdoms; td && *td; td = wcschr (td, L'\0'))
 | |
|         if (!wcscasecmp (td, domain))
 | |
|           return true;
 | |
|       return false;
 | |
|     }
 | |
|   virtual void *enumerate_caches () = 0;
 | |
|   virtual void *enumerate_file ();
 | |
|   virtual void *enumerate_builtin ();
 | |
|   virtual void *enumerate_local () = 0;
 | |
|   virtual void *enumerate_sam ();
 | |
|   virtual void *enumerate_ad ();
 | |
| 
 | |
| public:
 | |
|   void setent (bool _group, int _enums = 0, PCWSTR _enum_tdoms = NULL);
 | |
|   void *getent ();
 | |
|   void endent (bool _group);
 | |
| };
 | |
| 
 | |
| class pw_ent : public pg_ent
 | |
| {
 | |
|   void *enumerate_caches ();
 | |
|   void *enumerate_local ();
 | |
| public:
 | |
|   inline void setpwent (int _enums = 0, PCWSTR _enum_tdoms = NULL)
 | |
|     { setent (false, _enums, _enum_tdoms); }
 | |
|   struct passwd *getpwent ();
 | |
|   inline void endpwent () { endent (false); }
 | |
| };
 | |
| 
 | |
| class gr_ent : public pg_ent
 | |
| {
 | |
|   void *enumerate_caches ();
 | |
|   void *enumerate_local ();
 | |
| public:
 | |
|   inline void setgrent (int _enums = 0, PCWSTR _enum_tdoms = NULL)
 | |
|     { setent (true, _enums, _enum_tdoms); }
 | |
|   struct group *getgrent ();
 | |
|   inline void endgrent () { endent (true); }
 | |
| };
 | |
| 
 | |
| /* These inline methods have to be defined here so that pg_pwd and pg_grp
 | |
|    are defined. */
 | |
| inline BOOL cygsid::getfrompw (const struct passwd *pw)
 | |
|   { return (*this = pw ? (PSID) ((pg_pwd *) pw)->sid : NO_SID) != NO_SID; }
 | |
| 
 | |
| inline BOOL cygsid::getfromgr (const struct group *gr)
 | |
|   { return (*this = gr ? (PSID) ((pg_grp *) gr)->sid : NO_SID) != NO_SID; }
 | |
| 
 | |
| /* Use these functions if you just need the PSID. */
 | |
| inline PSID sidfromuid (uid_t uid, cyg_ldap *pldap)
 | |
|   {
 | |
|     struct passwd *pw = internal_getpwuid (uid, pldap);
 | |
|     if (pw)
 | |
|       return (PSID) ((pg_pwd *) pw)->sid;
 | |
|     return NO_SID;
 | |
|   }
 | |
| inline PSID sidfromgid (gid_t gid, cyg_ldap *pldap)
 | |
|   {
 | |
|     struct group *gr = internal_getgrgid (gid, pldap);
 | |
|     if (gr)
 | |
|       return (PSID) ((pg_grp *) gr)->sid;
 | |
|     return NO_SID;
 | |
|   }
 |