/* 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) (); char pwd_sep; 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); 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; }