1 /* sec_helper.cc: NT security helper functions
3 Copyright 2000, 2001 Cygnus Solutions.
5 Written by Corinna Vinschen <corinna@vinschen.de>
7 This file is part of Cygwin.
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
20 #include <sys/types.h>
28 #include "perprocess.h"
38 SID_IDENTIFIER_AUTHORITY sid_auth[] = {
39 {SECURITY_NULL_SID_AUTHORITY},
40 {SECURITY_WORLD_SID_AUTHORITY},
41 {SECURITY_LOCAL_SID_AUTHORITY},
42 {SECURITY_CREATOR_SID_AUTHORITY},
43 {SECURITY_NON_UNIQUE_AUTHORITY},
44 {SECURITY_NT_AUTHORITY}
48 convert_sid_to_string_sid (PSID psid, char *sid_str)
53 if (!psid || !sid_str)
55 strcpy (sid_str, "S-1-");
56 __small_sprintf(t, "%u", GetSidIdentifierAuthority (psid)->Value[5]);
58 for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i)
60 __small_sprintf(t, "-%lu", *GetSidSubAuthority (psid, i));
67 get_sid (PSID psid, DWORD s, DWORD cnt, DWORD *r)
71 if (!psid || s > 5 || cnt < 1 || cnt > 8)
74 InitializeSid(psid, &sid_auth[s], cnt);
75 for (i = 0; i < cnt; ++i)
76 memcpy ((char *) psid + 8 + sizeof (DWORD) * i, &r[i], sizeof (DWORD));
81 convert_string_sid_to_sid (PSID psid, const char *sid_str)
89 if (!sid_str || strncmp (sid_str, "S-1-", 4))
92 strcpy (sid_buf, sid_str);
94 for (t = sid_buf + 4, i = 0;
95 cnt < 8 && (t = strtok_r (t, "-", &lasts));
98 s = strtoul (t, NULL, 10);
100 r[cnt++] = strtoul (t, NULL, 10);
102 return get_sid (psid, s, cnt, r);
106 get_pw_sid (PSID sid, struct passwd *pw)
108 char *sp = pw->pw_gecos ? strrchr (pw->pw_gecos, ',') : NULL;
112 return convert_string_sid_to_sid (sid, ++sp) != NULL;
116 get_gr_sid (PSID sid, struct group *gr)
118 return convert_string_sid_to_sid (sid, gr->gr_passwd) != NULL;
124 static NO_COPY cygsid admin_sid (NULL);
127 convert_string_sid_to_sid (admin_sid.set (), "S-1-5-32-544");
134 static NO_COPY cygsid system_sid (NULL);
137 convert_string_sid_to_sid (system_sid.set (), "S-1-5-18");
142 get_creator_owner_sid ()
144 static NO_COPY cygsid owner_sid (NULL);
147 convert_string_sid_to_sid (owner_sid.set (), "S-1-3-0");
154 static NO_COPY cygsid world_sid (NULL);
157 convert_string_sid_to_sid (world_sid.set (), "S-1-1-0");
162 get_id_from_sid (PSID psid, BOOL search_grp, int *type)
164 if (!IsValidSid (psid))
167 small_printf ("IsValidSid failed with %E");
171 /* First try to get SID from passwd or group entry */
180 for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
182 if (get_pw_sid (sid, pw) && sid == psid)
195 if (search_grp || type)
198 for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
200 if (get_gr_sid (sid, gr) && sid == psid)
215 /* We use the RID as default UID/GID */
216 int id = *GetSidSubAuthority(psid, *GetSidSubAuthorityCount(psid) - 1);
219 * The RID maybe -1 if accountname == computername.
220 * In this case we search for the accountname in the passwd and group files.
221 * If type is needed, we search in each case.
223 if (id == -1 || type)
225 char account[UNLEN + 1];
226 char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
227 DWORD acc_len = UNLEN + 1;
228 DWORD dom_len = INTERNET_MAX_HOST_NAME_LENGTH + 1;
229 SID_NAME_USE acc_type;
231 if (!LookupAccountSid (NULL, psid, account, &acc_len,
232 domain, &dom_len, &acc_type))
242 case SidTypeWellKnownGroup:
247 struct group *gr = getgrnam (account);
257 struct passwd *pw = getpwnam (account);
272 get_id_from_sid (PSID psid, BOOL search_grp)
274 return get_id_from_sid (psid, search_grp, NULL);
278 legal_sid_type (SID_NAME_USE type)
280 return type == SidTypeUser || type == SidTypeGroup
281 || SidTypeAlias || SidTypeWellKnownGroup;
285 is_grp_member (uid_t uid, gid_t gid)
287 extern int getgroups (int, gid_t *, gid_t, const char *);
288 BOOL grp_member = TRUE;
290 struct passwd *pw = getpwuid (uid);
291 gid_t grps[NGROUPS_MAX];
292 int cnt = getgroups (NGROUPS_MAX, grps,
293 pw ? pw->pw_gid : myself->gid,
294 pw ? pw->pw_name : cygheap->user.name ());
296 for (i = 0; i < cnt; ++i)
299 grp_member = (i < cnt);
303 #define SIDLEN (sidlen = MAX_SID_LEN, &sidlen)
304 #define DOMLEN (domlen = INTERNET_MAX_HOST_NAME_LENGTH, &domlen)
307 lookup_name (const char *name, const char *logsrv, PSID ret_sid)
311 char domuser[INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 2];
312 char dom[INTERNET_MAX_HOST_NAME_LENGTH + 1];
314 SID_NAME_USE acc_type;
316 debug_printf ("name : %s", name ? name : "NULL");
321 if (cygheap->user.domain ())
323 strcat (strcat (strcpy (domuser, cygheap->user.domain ()), "\\"), name);
324 if (LookupAccountName (NULL, domuser, sid, SIDLEN, dom, DOMLEN, &acc_type)
325 && legal_sid_type (acc_type))
327 if (logsrv && *logsrv
328 && LookupAccountName (logsrv, domuser, sid, SIDLEN,
329 dom, DOMLEN, &acc_type)
330 && legal_sid_type (acc_type))
333 if (logsrv && *logsrv)
335 if (LookupAccountName (logsrv, name, sid, SIDLEN, dom, DOMLEN, &acc_type)
336 && legal_sid_type (acc_type))
338 if (acc_type == SidTypeDomain)
340 strcat (strcat (strcpy (domuser, dom), "\\"), name);
341 if (LookupAccountName (logsrv, domuser, sid, SIDLEN,
342 dom, DOMLEN, &acc_type))
346 if (LookupAccountName (NULL, name, sid, SIDLEN, dom, DOMLEN, &acc_type)
347 && legal_sid_type (acc_type))
349 if (acc_type == SidTypeDomain)
351 strcat (strcat (strcpy (domuser, dom), "\\"), name);
352 if (LookupAccountName (NULL, domuser, sid, SIDLEN, dom, DOMLEN,&acc_type))
355 debug_printf ("LookupAccountName(%s) %E", name);
360 debug_printf ("sid : [%d]", *GetSidSubAuthority((PSID) sid,
361 *GetSidSubAuthorityCount((PSID) sid) - 1));
364 memcpy (ret_sid, sid, sidlen);
373 set_process_privilege (const char *privilege, BOOL enable)
375 HANDLE hToken = NULL;
377 TOKEN_PRIVILEGES new_priv;
380 if (!OpenProcessToken (hMainProc, TOKEN_ADJUST_PRIVILEGES, &hToken))
386 if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
392 new_priv.PrivilegeCount = 1;
393 new_priv.Privileges[0].Luid = restore_priv;
394 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
396 if (!AdjustTokenPrivileges (hToken, FALSE, &new_priv, 0, NULL, NULL))
406 CloseHandle (hToken);
408 syscall_printf ("%d = set_process_privilege (%s, %d)",ret, privilege, enable);