Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2001-04-20 17:02:32 +0400
committerCorinna Vinschen <corinna@vinschen.de>2001-04-20 17:02:32 +0400
commitc0d1968a18c75ffb160c840c474b9b1e095cd541 (patch)
tree99ad46ce44b67c9c6c175bb8b61ca46e18d57336 /winsup/cygwin/sec_helper.cc
parent125261f738b1ae42ac89c50d06478b6955be1d73 (diff)
* Makefile.in: Add object files `sec_helper.cc' and `sec_acl.cc'.
* security.cc: Swap out several functions. * sec_acl.cc: New file. Move Sun compatibel ACL functions from `security.cc' to here. * sec_helper.cc: New file. Move security helper functions from `security.cc' to here. * security.h: Changed to accomodate the above changes. * grp.cc: Replace `group_in_memory_p' by `group_state'. Eliminate group_sem throughout. (enum grp_state): New enumeration type. (read_etc_group): Make race safe. * security.cc: Eliminate group_sem throughout.
Diffstat (limited to 'winsup/cygwin/sec_helper.cc')
-rw-r--r--winsup/cygwin/sec_helper.cc399
1 files changed, 399 insertions, 0 deletions
diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc
new file mode 100644
index 000000000..1771d934c
--- /dev/null
+++ b/winsup/cygwin/sec_helper.cc
@@ -0,0 +1,399 @@
+/* sec_helper.cc: NT security helper functions
+
+ Copyright 2000, 2001 Cygnus Solutions.
+
+ Written by Corinna Vinschen <corinna@vinschen.de>
+
+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. */
+
+#include "winsup.h"
+#include <grp.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/acl.h>
+#include <ctype.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include "cygerrno.h"
+#include "perprocess.h"
+#include "fhandler.h"
+#include "path.h"
+#include "dtable.h"
+#include "sync.h"
+#include "sigproc.h"
+#include "pinfo.h"
+#include "cygheap.h"
+#include "security.h"
+
+SID_IDENTIFIER_AUTHORITY sid_auth[] = {
+ {SECURITY_NULL_SID_AUTHORITY},
+ {SECURITY_WORLD_SID_AUTHORITY},
+ {SECURITY_LOCAL_SID_AUTHORITY},
+ {SECURITY_CREATOR_SID_AUTHORITY},
+ {SECURITY_NON_UNIQUE_AUTHORITY},
+ {SECURITY_NT_AUTHORITY}
+};
+
+char *
+convert_sid_to_string_sid (PSID psid, char *sid_str)
+{
+ char t[32];
+ DWORD i;
+
+ if (!psid || !sid_str)
+ return NULL;
+ strcpy (sid_str, "S-1-");
+ __small_sprintf(t, "%u", GetSidIdentifierAuthority (psid)->Value[5]);
+ strcat (sid_str, t);
+ for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i)
+ {
+ __small_sprintf(t, "-%lu", *GetSidSubAuthority (psid, i));
+ strcat (sid_str, t);
+ }
+ return sid_str;
+}
+
+PSID
+get_sid (PSID psid, DWORD s, DWORD cnt, DWORD *r)
+{
+ DWORD i;
+
+ if (!psid || s > 5 || cnt < 1 || cnt > 8)
+ return NULL;
+
+ InitializeSid(psid, &sid_auth[s], cnt);
+ for (i = 0; i < cnt; ++i)
+ memcpy ((char *) psid + 8 + sizeof (DWORD) * i, &r[i], sizeof (DWORD));
+ return psid;
+}
+
+PSID
+convert_string_sid_to_sid (PSID psid, const char *sid_str)
+{
+ char sid_buf[256];
+ char *t, *lasts;
+ DWORD cnt = 0;
+ DWORD s = 0;
+ DWORD i, r[8];
+
+ if (!sid_str || strncmp (sid_str, "S-1-", 4))
+ return NULL;
+
+ strcpy (sid_buf, sid_str);
+
+ for (t = sid_buf + 4, i = 0;
+ cnt < 8 && (t = strtok_r (t, "-", &lasts));
+ t = NULL, ++i)
+ if (i == 0)
+ s = strtoul (t, NULL, 10);
+ else
+ r[cnt++] = strtoul (t, NULL, 10);
+
+ return get_sid (psid, s, cnt, r);
+}
+
+BOOL
+get_pw_sid (PSID sid, struct passwd *pw)
+{
+ char *sp = pw->pw_gecos ? strrchr (pw->pw_gecos, ',') : NULL;
+
+ if (!sp)
+ return FALSE;
+ return convert_string_sid_to_sid (sid, ++sp) != NULL;
+}
+
+BOOL
+get_gr_sid (PSID sid, struct group *gr)
+{
+ return convert_string_sid_to_sid (sid, gr->gr_passwd) != NULL;
+}
+
+PSID
+get_admin_sid ()
+{
+ static NO_COPY char admin_sid_buf[MAX_SID_LEN];
+ static NO_COPY PSID admin_sid = NULL;
+
+ if (!admin_sid)
+ {
+ admin_sid = (PSID) admin_sid_buf;
+ convert_string_sid_to_sid (admin_sid, "S-1-5-32-544");
+ }
+ return admin_sid;
+}
+
+PSID
+get_system_sid ()
+{
+ static NO_COPY char system_sid_buf[MAX_SID_LEN];
+ static NO_COPY PSID system_sid = NULL;
+
+ if (!system_sid)
+ {
+ system_sid = (PSID) system_sid_buf;
+ convert_string_sid_to_sid (system_sid, "S-1-5-18");
+ }
+ return system_sid;
+}
+
+PSID
+get_creator_owner_sid ()
+{
+ static NO_COPY char owner_sid_buf[MAX_SID_LEN];
+ static NO_COPY PSID owner_sid = NULL;
+
+ if (!owner_sid)
+ {
+ owner_sid = (PSID) owner_sid_buf;
+ convert_string_sid_to_sid (owner_sid, "S-1-3-0");
+ }
+ return owner_sid;
+}
+
+PSID
+get_world_sid ()
+{
+ static NO_COPY char world_sid_buf[MAX_SID_LEN];
+ static NO_COPY PSID world_sid = NULL;
+
+ if (!world_sid)
+ {
+ world_sid = (PSID) world_sid_buf;
+ convert_string_sid_to_sid (world_sid, "S-1-1-0");
+ }
+ return world_sid;
+}
+
+int
+get_id_from_sid (PSID psid, BOOL search_grp, int *type)
+{
+ if (!IsValidSid (psid))
+ {
+ __seterrno ();
+ small_printf ("IsValidSid failed with %E");
+ return -1;
+ }
+
+ /* First try to get SID from passwd or group entry */
+ if (allow_ntsec)
+ {
+ char sidbuf[MAX_SID_LEN];
+ PSID sid = (PSID) sidbuf;
+ int id = -1;
+
+ if (!search_grp)
+ {
+ struct passwd *pw;
+ while ((pw = getpwent ()) != NULL)
+ {
+ if (get_pw_sid (sid, pw) && EqualSid (psid, sid))
+ {
+ id = pw->pw_uid;
+ break;
+ }
+ }
+ endpwent ();
+ if (id >= 0)
+ {
+ if (type)
+ *type = USER;
+ return id;
+ }
+ }
+ if (search_grp || type)
+ {
+ struct group *gr;
+ while ((gr = getgrent ()) != NULL)
+ {
+ if (get_gr_sid (sid, gr) && EqualSid (psid, sid))
+ {
+ id = gr->gr_gid;
+ break;
+ }
+ }
+ endgrent ();
+ if (id >= 0)
+ {
+ if (type)
+ *type = GROUP;
+ return id;
+ }
+ }
+ }
+
+ /* We use the RID as default UID/GID */
+ int id = *GetSidSubAuthority(psid, *GetSidSubAuthorityCount(psid) - 1);
+
+ /*
+ * The RID maybe -1 if accountname == computername.
+ * In this case we search for the accountname in the passwd and group files.
+ * If type is needed, we search in each case.
+ */
+ if (id == -1 || type)
+ {
+ char account[MAX_USER_NAME];
+ char domain[MAX_COMPUTERNAME_LENGTH+1];
+ DWORD acc_len = MAX_USER_NAME;
+ DWORD dom_len = MAX_COMPUTERNAME_LENGTH+1;
+ SID_NAME_USE acc_type;
+
+ if (!LookupAccountSid (NULL, psid, account, &acc_len,
+ domain, &dom_len, &acc_type))
+ {
+ __seterrno ();
+ return -1;
+ }
+
+ switch (acc_type)
+ {
+ case SidTypeGroup:
+ case SidTypeAlias:
+ case SidTypeWellKnownGroup:
+ if (type)
+ *type = GROUP;
+ if (id == -1)
+ {
+ struct group *gr = getgrnam (account);
+ if (gr)
+ id = gr->gr_gid;
+ }
+ break;
+ case SidTypeUser:
+ if (type)
+ *type = USER;
+ if (id == -1)
+ {
+ struct passwd *pw = getpwnam (account);
+ if (pw)
+ id = pw->pw_uid;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (id == -1)
+ id = getuid ();
+ return id;
+}
+
+int
+get_id_from_sid (PSID psid, BOOL search_grp)
+{
+ return get_id_from_sid (psid, search_grp, NULL);
+}
+
+BOOL
+legal_sid_type (SID_NAME_USE type)
+{
+ return type == SidTypeUser || type == SidTypeGroup
+ || SidTypeAlias || SidTypeWellKnownGroup;
+}
+
+BOOL
+is_grp_member (uid_t uid, gid_t gid)
+{
+ extern int getgroups (int, gid_t *, gid_t, const char *);
+ BOOL grp_member = TRUE;
+
+ struct passwd *pw = getpwuid (uid);
+ gid_t grps[NGROUPS_MAX];
+ int cnt = getgroups (NGROUPS_MAX, grps,
+ pw ? pw->pw_gid : myself->gid,
+ pw ? pw->pw_name : cygheap->user.name ());
+ int i;
+ for (i = 0; i < cnt; ++i)
+ if (grps[i] == gid)
+ break;
+ grp_member = (i < cnt);
+ return grp_member;
+}
+
+BOOL
+lookup_name (const char *name, const char *logsrv, PSID ret_sid)
+{
+ char sidbuf[MAX_SID_LEN];
+ PSID sid = (PSID) sidbuf;
+ DWORD sidlen;
+ char domuser[MAX_COMPUTERNAME_LENGTH+MAX_USER_NAME+1];
+ char dom[MAX_COMPUTERNAME_LENGTH+1];
+ DWORD domlen;
+ SID_NAME_USE acc_type;
+
+ debug_printf ("name : %s", name ? name : "NULL");
+
+ if (!name)
+ return FALSE;
+
+ if (cygheap->user.domain ())
+ {
+ strcat (strcat (strcpy (domuser, cygheap->user.domain ()), "\\"), name);
+ if (LookupAccountName (NULL, domuser,
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
+ &acc_type)
+ && legal_sid_type (acc_type))
+ goto got_it;
+ if (logsrv && *logsrv
+ && LookupAccountName (logsrv, domuser,
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH,&domlen),
+ &acc_type)
+ && legal_sid_type (acc_type))
+ goto got_it;
+ }
+ if (logsrv && *logsrv)
+ {
+ if (LookupAccountName (logsrv, name,
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
+ &acc_type)
+ && legal_sid_type (acc_type))
+ goto got_it;
+ if (acc_type == SidTypeDomain)
+ {
+ strcat (strcat (strcpy (domuser, dom), "\\"), name);
+ if (LookupAccountName (logsrv, domuser,
+ sid,(sidlen = MAX_SID_LEN, &sidlen),
+ dom,(domlen = MAX_COMPUTERNAME_LENGTH,&domlen),
+ &acc_type))
+ goto got_it;
+ }
+ }
+ if (LookupAccountName (NULL, name,
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = 100, &domlen),
+ &acc_type)
+ && legal_sid_type (acc_type))
+ goto got_it;
+ if (acc_type == SidTypeDomain)
+ {
+ strcat (strcat (strcpy (domuser, dom), "\\"), name);
+ if (LookupAccountName (NULL, domuser,
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
+ &acc_type))
+ goto got_it;
+ }
+ debug_printf ("LookupAccountName(%s) %E", name);
+ __seterrno ();
+ return FALSE;
+
+got_it:
+ debug_printf ("sid : [%d]", *GetSidSubAuthority((PSID) sid,
+ *GetSidSubAuthorityCount((PSID) sid) - 1));
+
+ if (ret_sid)
+ memcpy (ret_sid, sid, sidlen);
+
+ return TRUE;
+}