pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS

Difference between
modified post 928609bd by Anonymous on Fri 24th May 2024 13:38
original post 7e33d2 by Anonymous on Fri 24th May 2024 13:11
Download diff
Show old version | new version | both versions

    
11
22
/*
33
 * MIT License
44
 *
55
 * Copyright (c) 2024 Roland Mainz <roland.mainz@nrubsig.org>
66
 *
77
 * Permission is hereby granted, free of charge, to any person obtaining a copy
88
 * of this software and associated documentation files (the "Software"), to deal
99
 * in the Software without restriction, including without limitation the rights
1010
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111
 * copies of the Software, and to permit persons to whom the Software is
1212
 * furnished to do so, subject to the following conditions:
1313
 *
1414
 * The above copyright notice and this permission notice shall be included in all
1515
 * copies or substantial portions of the Software.
1616
 *
1717
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
 * SOFTWARE.
2424
 */
2525
2626
/*
2727
 * winsg.c - run Win32 or Cygwin program with a different group
2828
 *
2929
 * Written by Roland Mainz <roland.mainz@nrubsig.org>
3030
 */
3131
3232
#include <windows.h>
3333
#include <stdio.h>
3434
#include <stdbool.h>
3535
#include <Lmcons.h>
3636
#include <process.h>
3737
3838
/*
3939
 * Performance hack:
4040
 * GETTOKINFO_EXTRA_BUFFER - extra space for more data
4141
 * |GetTokenInformation()| for |TOKEN_USER| and |TOKEN_PRIMARY_GROUP|
4242
 * always fails in Win10 with |ERROR_INSUFFICIENT_BUFFER| if you
4343
 * just pass the |sizeof(TOKEN_*)| value. Instead of calling
4444
 * |GetTokenInformation()| with |NULL| arg to obtain the size to
4545
 * allocate we just provide 2048 bytes of extra space after the
4646
 * |TOKEN_*| size, and pray it is enough
4747
 */
4848
#define GETTOKINFO_EXTRA_BUFFER (2048)
4949
5050
bool get_token_primarygroup_name(HANDLE tok, char *out_buffer)
5151
{
5252
    DWORD tokdatalen;
5353
    PTOKEN_PRIMARY_GROUP ptpgroup;
5454
    PSID pgsid;
5555
    DWORD namesize = GNLEN+1;
5656
    char domainbuffer[UNLEN+1];
5757
    DWORD domainbuffer_size = sizeof(domainbuffer);
5858
    SID_NAME_USE name_use;
5959
6060
    tokdatalen = sizeof(TOKEN_PRIMARY_GROUP)+GETTOKINFO_EXTRA_BUFFER;
6161
    ptpgroup = _alloca(tokdatalen);
6262
    if (!GetTokenInformation(tok, TokenPrimaryGroup, ptpgroup,
6363
        tokdatalen, &tokdatalen)) {
6464
        (void)fprintf(stderr, "get_token_primarygroup_name: "
6565
            "GetTokenInformation(tok=0x%p, TokenPrimaryGroup) failed, "
6666
            "status=%d\n",
6767
            (void *)tok, (int)GetLastError());
6868
        return false;
6969
    }
7070
7171
    pgsid = ptpgroup->PrimaryGroup;
7272
7373
    if (!LookupAccountSidA(NULL, pgsid, out_buffer, &namesize,
7474
        domainbuffer, &domainbuffer_size, &name_use)) {
7575
        (void)fprintf(stderr, "get_token_primarygroup_name: "
7676
            "LookupAccountSidA() failed, status=%d\n",
7777
            (int)GetLastError());
7878
        return false;
7979
    }
8080
8181
    return true;
8282
}
8383
84-
bool set_token_primarygroup_name(HANDLE tok, const char *new_groupname)
84+
bool is_group_in_token(HANDLE tok, PSID qsid)
8585
{
8686
    DWORD tokdatalen;
87-
    TOKEN_PRIMARY_GROUP tpgroup;
87+
    PTOKEN_GROUPS ptgroups;
9488
95-
    if (!LookupAccountNameA(NULL, new_groupname,
89+
    tokdatalen = sizeof(TOKEN_GROUPS)+GETTOKINFO_EXTRA_BUFFER;
96-
        pgsid, &pgsid_size, domainbuffer, &domainbuffer_size, &name_use)) {
90+
    ptgroups = _alloca(tokdatalen);
97-
        (void)fprintf(stderr, "set_token_primarygroup_name: "
91+
    if (!GetTokenInformation(tok, TokenGroups, ptgroups,
98-
            "LookupAccountNameA() failed.\n");
92+
        tokdatalen, &tokdatalen)) {
93+
        (void)fprintf(stderr, "is_group_in_token: "
9997
        return false;
10098
    }
10199
102-
    tokdatalen = sizeof(TOKEN_PRIMARY_GROUP);
100+
    int i;
103-
    tpgroup.PrimaryGroup = pgsid;
101+
    (void)fprintf(stderr, "is_group_in_token: got %d groups\n", (int)ptgroups->GroupCount);
104-
    if (!SetTokenInformation(tok, TokenPrimaryGroup,
102+
    for (i = 0 ; i < ptgroups->GroupCount ; i++) {
105-
        &tpgroup, tokdatalen)) {
103+
        if (EqualSid(qsid, ptgroups->Groups[i].Sid) &&
106-
        (void)fprintf(stderr, "set_token_primarygroup_name: "
104+
            (ptgroups->Groups[i].Attributes & SE_GROUP_ENABLED)) {
107-
            "SetTokenInformation(tok=0x%p, TokenPrimaryGroup) failed, "
105+
            (void)puts("#match");
106+
            return true;
111107
    }
108+
    }
112109
113-
    return true;
110+
    (void)puts("#no match");
115111
116-
enum shelltype {
112+
    return false;
117-
    SHELLTYPE_NOT_SET = 0,
113+
}
122114
123-
int main(int ac, char *av[])
115+
bool set_token_primarygroup_name(HANDLE tok, const char *new_groupname)
124116
{
125-
    char pgroupname[GNLEN+1];
117+
    DWORD tokdatalen;
126-
    enum shelltype st = SHELLTYPE_NOT_SET;
118+
    TOKEN_PRIMARY_GROUP tpgroup;
127-
    int cmd_arg_index = -1;
119+
    char sidbuff[SECURITY_MAX_SID_SIZE+1];
128-
    const char *newgrpname = NULL;
120+
    PSID pgsid = (PSID)sidbuff;
129-
    int subcmdret = EXIT_FAILURE;
121+
    DWORD pgsid_size = sizeof(sidbuff);
122+
    char domainbuffer[UNLEN+1];
130125
131-
    int i;
126+
    if (!LookupAccountNameA(NULL, new_groupname,
127+
        pgsid, &pgsid_size, domainbuffer, &domainbuffer_size, &name_use)) {
132132
133-
    for (i=1 ; i < ac ; i++) {
133+
#if 1
134-
        (void)fprintf(stderr, "# i=%d, av[i]='%s'\n", i, av[i]);
134+
    if (!is_group_in_token(tok, pgsid)) {
135-
135+
        (void)fprintf(stderr, "set_token_primarygroup_name: "
136-
        if (!strcmp(av[i], "-")) {
136+
            "group '%s' is not a member.\n", new_groupname);
137-
            (void)fprintf(stderr, "%s: Run in new login not supported yet.\n", av[0]);
137+
        return false;
139138
        }
140-
        else if (!strcmp(av[i], "-c")) {
139+
#else
141-
            st = SHELLTYPE_SYSTEM;
140+
    BOOL is_member = FALSE;
142-
            cmd_arg_index = i+1;
141+
    if (!CheckTokenMembership(tok, pgsid, &is_member)) {
143-
            break;
142+
        (void)fprintf(stderr, "set_token_primarygroup_name: "
143+
            "CheckTokenMembership() failed, status=%d.\n", (int)GetLastError());
144145
        }
145-
        else if (!strcmp(av[i], "/C")) {
146+
146-
            st = SHELLTYPE_CMD;
147+
    if (!is_member) {
147-
            cmd_arg_index = i+1;
148+
        (void)fprintf(stderr, "set_token_primarygroup_name: "
148-
            break;
149+
            "group '%s' is not a member.\n", new_groupname);
150+
        return false;
149151
        }
150-
        else if (!strcmp(av[i], "-g")) {
152+
#endif
159153
160-
            cmd_arg_index = i+1;
154+
    tokdatalen = sizeof(TOKEN_PRIMARY_GROUP);
161-
            st = SHELLTYPE_NONE;
155+
    tpgroup.PrimaryGroup = pgsid;
162-
            break;
156+
    if (!SetTokenInformation(tok, TokenPrimaryGroup,
157+
        &tpgroup, tokdatalen)) {
163163
        }
164+

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at