Beispiel #1
0
UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
{
    WCHAR squished_pc[GUID_SIZE];
    WCHAR keypath[0x200];
    LPWSTR usersid;
    UINT r;

    TRACE("%s\n", debugstr_w(szProductCode));

    if (!squash_guid(szProductCode, squished_pc))
        return ERROR_FUNCTION_FAILED;

    TRACE("squished (%s)\n", debugstr_w(squished_pc));

    r = get_user_sid(&usersid);
    if (r != ERROR_SUCCESS || !usersid)
    {
        ERR("Failed to retrieve user SID: %d\n", r);
        return r;
    }

    sprintfW(keypath, szInstaller_LocalManagedProd_fmt, usersid, squished_pc);
    LocalFree(usersid);

    if (create)
        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);

    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
}
// initialize the registry. setup default keys to use
void os_init_registry_stuff(const char *company, const char *app, const char *version)
{
	if (company) {
		strcpy_s(szCompanyName, company);
	}
	else {
		strcpy_s(szCompanyName, Osreg_company_name);
	}

	if (app) {
		strcpy_s(szAppName, app);
	}
	else {
		strcpy_s(szAppName, Osreg_app_name);
	}

#ifdef WIN32
	OSVERSIONINFO versionInfo;
	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&versionInfo);

	// Windows Vista is 6.0 which is the first version requiring this
	if (versionInfo.dwMajorVersion >= 6)
	{
		userSIDValid = get_user_sid(userSID);
	}
#endif

	Os_reg_inited = 1;
}
Beispiel #3
0
UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
{
    UINT rc;
    WCHAR squished_pc[GUID_SIZE];
    WCHAR keypath[0x200];
    LPWSTR usersid;

    TRACE("%s\n", debugstr_w(szProduct));
    if (!squash_guid(szProduct, squished_pc))
        return ERROR_FUNCTION_FAILED;
    TRACE("squished (%s)\n", debugstr_w(squished_pc));

    rc = get_user_sid(&usersid);
    if (rc != ERROR_SUCCESS || !usersid)
    {
        ERR("Failed to retrieve user SID: %d\n", rc);
        return rc;
    }

    sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);

    if (create)
        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
    else
        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);

    LocalFree(usersid);
    return rc;
}
Beispiel #4
0
bool getsids(char **error)
{
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-braces"
#endif
    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
#ifdef __clang__
#pragma clang diagnostic pop
#endif

    bool ret = false;

    *error = NULL;

    if (!usersid) {
        if ((usersid = get_user_sid()) == NULL) {
            *error = dupprintf("unable to construct SID for current user: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    if (!worldsid) {
        if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
                                      0, 0, 0, 0, 0, 0, 0, &worldsid)) {
            *error = dupprintf("unable to construct SID for world: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    if (!networksid) {
        if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID,
                                      0, 0, 0, 0, 0, 0, 0, &networksid)) {
            *error = dupprintf("unable to construct SID for "
                               "local same-user access only: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    ret = true;

 cleanup:
    return ret;
}
Beispiel #5
0
UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY *key,
                                               BOOL create)
{
    UINT rc;
    LPWSTR usersid;

    rc = get_user_sid(&usersid);
    if (rc != ERROR_SUCCESS || !usersid)
    {
        ERR("Failed to retrieve user SID: %d\n", rc);
        return rc;
    }

    rc = MSIREG_OpenInstallProps(szProduct, usersid, key, create);

    LocalFree(usersid);
    return rc;
}
Beispiel #6
0
int getsids(char *error)
{
    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
    int ret;

    error=NULL;

    if (!usersid) {
        if ((usersid = get_user_sid()) == NULL) {
            error = dupprintf("unable to construct SID for current user: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    if (!worldsid) {
        if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
                                      0, 0, 0, 0, 0, 0, 0, &worldsid)) {
            error = dupprintf("unable to construct SID for world: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    if (!networksid) {
        if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID,
                                      0, 0, 0, 0, 0, 0, 0, &networksid)) {
            error = dupprintf("unable to construct SID for "
                               "local same-user access only: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    ret=TRUE;

 cleanup:
    if (ret) {
      sfree(error);
      error = NULL;
    }
    return ret;
}
Beispiel #7
0
UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent)
{
    UINT rc;
    WCHAR comp[GUID_SIZE];
    WCHAR keypath[0x200];
    LPWSTR usersid;

    TRACE("%s\n", debugstr_w(szComponent));
    if (!squash_guid(szComponent, comp))
        return ERROR_FUNCTION_FAILED;
    TRACE("squished (%s)\n", debugstr_w(comp));

    rc = get_user_sid(&usersid);
    if (rc != ERROR_SUCCESS || !usersid)
    {
        ERR("Failed to retrieve user SID: %d\n", rc);
        return rc;
    }

    sprintfW(keypath, szUserDataComp_fmt, usersid, comp);

    LocalFree(usersid);
    return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
}
Beispiel #8
0
/*
 * Create an access check structure, the format depends on the version parameter.
 * If broken is specified then we create a stucture that isn't conform to the 
 * specification.
 *
 * If the structure can't be created then NULL is returned.
 */
static DATA_BLOB *create_access_check(struct torture_context *tctx,
				      struct dcerpc_pipe *p,
				      TALLOC_CTX *mem_ctx,
				      const char *user,
				      bool broken,
				      uint32_t version)
{
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
	enum ndr_err_code ndr_err;
	const struct dom_sid *sid = get_user_sid(tctx, p, tmp_ctx, user);

	if (sid == NULL) {
		return NULL;
	}

	if (version == 2) {
		struct bkrp_access_check_v2 access_struct;
		struct sha sctx;
		uint8_t nonce[32];

		ZERO_STRUCT(access_struct);
		generate_random_buffer(nonce, sizeof(nonce));
		access_struct.nonce_len = sizeof(nonce);
		access_struct.nonce = nonce;
		access_struct.sid = *sid;

		ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
				(ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v2);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			return NULL;
		}

		/*
		 * We pushed the whole structure including a null hash
		 * but the hash need to be calculated only up to the hash field
		 * so we reduce the size of what has to be calculated
		 */

		SHA1_Init(&sctx);
		SHA1_Update(&sctx, blob->data,
			    blob->length - sizeof(access_struct.hash));
		SHA1_Final(blob->data + blob->length - sizeof(access_struct.hash),
			   &sctx);

		/* Altering the SHA */
		if (broken) {
			blob->data[blob->length - 1]++;
		}
	}

	if (version == 3) {
		struct bkrp_access_check_v3 access_struct;
		struct hc_sha512state sctx;
		uint8_t nonce[32];

		ZERO_STRUCT(access_struct);
		generate_random_buffer(nonce, sizeof(nonce));
		access_struct.nonce_len = sizeof(nonce);
		access_struct.nonce = nonce;
		access_struct.sid = *sid;

		ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
				(ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v3);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			return NULL;
		}

		/*We pushed the whole structure including a null hash
		* but the hash need to be calculated only up to the hash field
		* so we reduce the size of what has to be calculated
		*/

		SHA512_Init(&sctx);
		SHA512_Update(&sctx, blob->data,
			      blob->length - sizeof(access_struct.hash));
		SHA512_Final(blob->data + blob->length - sizeof(access_struct.hash),
			     &sctx);

		/* Altering the SHA */
		if (broken) {
			blob->data[blob->length -1]++;
		}
	}
	talloc_free(tmp_ctx);
	return blob;
}
Beispiel #9
0
agent_pending_query *agent_query(
    strbuf *query, void **out, int *outlen,
    void (*callback)(void *, void *, int), void *callback_ctx)
{
    HWND hwnd;
    char *mapname;
    HANDLE filemap;
    unsigned char *p, *ret;
    int id, retlen;
    COPYDATASTRUCT cds;
    SECURITY_ATTRIBUTES sa, *psa;
    PSECURITY_DESCRIPTOR psd = NULL;
    PSID usersid = NULL;

    *out = NULL;
    *outlen = 0;

    if (query->len > AGENT_MAX_MSGLEN)
        return NULL;                   /* query too large */

    hwnd = FindWindow("Pageant", "Pageant");
    if (!hwnd)
	return NULL;		       /* *out == NULL, so failure */
    mapname = dupprintf("PageantRequest%08x", (unsigned)GetCurrentThreadId());

    psa = NULL;
#ifndef NO_SECURITY
    if (got_advapi()) {
        /*
         * Make the file mapping we create for communication with
         * Pageant owned by the user SID rather than the default. This
         * should make communication between processes with slightly
         * different contexts more reliable: in particular, command
         * prompts launched as administrator should still be able to
         * run PSFTPs which refer back to the owning user's
         * unprivileged Pageant.
         */
        usersid = get_user_sid();

        if (usersid) {
            psd = (PSECURITY_DESCRIPTOR)
                LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
            if (psd) {
                if (p_InitializeSecurityDescriptor
                    (psd, SECURITY_DESCRIPTOR_REVISION) &&
                    p_SetSecurityDescriptorOwner(psd, usersid, false)) {
                    sa.nLength = sizeof(sa);
                    sa.bInheritHandle = true;
                    sa.lpSecurityDescriptor = psd;
                    psa = &sa;
                } else {
                    LocalFree(psd);
                    psd = NULL;
                }
            }
        }
    }
#endif /* NO_SECURITY */

    filemap = CreateFileMapping(INVALID_HANDLE_VALUE, psa, PAGE_READWRITE,
				0, AGENT_MAX_MSGLEN, mapname);
    if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) {
        sfree(mapname);
	return NULL;		       /* *out == NULL, so failure */
    }
    p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
    strbuf_finalise_agent_query(query);
    memcpy(p, query->s, query->len);
    cds.dwData = AGENT_COPYDATA_ID;
    cds.cbData = 1 + strlen(mapname);
    cds.lpData = mapname;

    /*
     * The user either passed a null callback (indicating that the
     * query is required to be synchronous) or CreateThread failed.
     * Either way, we need a synchronous request.
     */
    id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
    if (id > 0) {
	retlen = 4 + GET_32BIT_MSB_FIRST(p);
	ret = snewn(retlen, unsigned char);
	if (ret) {
	    memcpy(ret, p, retlen);
	    *out = ret;
	    *outlen = retlen;
	}
    }
Beispiel #10
0
Socket new_named_pipe_client(const char *pipename, Plug plug)
{
    HANDLE pipehandle;
    PSID usersid, pipeowner;
    PSECURITY_DESCRIPTOR psd;
    char *err;
    Socket ret;

    assert(strncmp(pipename, "\\\\.\\pipe\\", 9) == 0);
    assert(strchr(pipename + 9, '\\') == NULL);

    while (1) {
        pipehandle = CreateFile(pipename, GENERIC_READ | GENERIC_WRITE,
                                0, NULL, OPEN_EXISTING,
                                FILE_FLAG_OVERLAPPED, NULL);

        if (pipehandle != INVALID_HANDLE_VALUE)
            break;

        if (GetLastError() != ERROR_PIPE_BUSY) {
            err = dupprintf("Unable to open named pipe '%s': %s",
                            pipename, win_strerror(GetLastError()));
            ret = new_error_socket(err, plug);
            sfree(err);
            return ret;
        }

        /*
         * If we got ERROR_PIPE_BUSY, wait for the server to
         * create a new pipe instance. (Since the server is
         * expected to be winnps.c, which will do that immediately
         * after a previous connection is accepted, that shouldn't
         * take excessively long.)
         */
        if (!WaitNamedPipe(pipename, NMPWAIT_USE_DEFAULT_WAIT)) {
            err = dupprintf("Error waiting for named pipe '%s': %s",
                            pipename, win_strerror(GetLastError()));
            ret = new_error_socket(err, plug);
            sfree(err);
            return ret;
        }
    }

    if ((usersid = get_user_sid()) == NULL) {
        CloseHandle(pipehandle);
        err = dupprintf("Unable to get user SID");
        ret = new_error_socket(err, plug);
        sfree(err);
        return ret;
    }

    if (p_GetSecurityInfo(pipehandle, SE_KERNEL_OBJECT,
                          OWNER_SECURITY_INFORMATION,
                          &pipeowner, NULL, NULL, NULL,
                          &psd) != ERROR_SUCCESS) {
        err = dupprintf("Unable to get named pipe security information: %s",
                        win_strerror(GetLastError()));
        ret = new_error_socket(err, plug);
        sfree(err);
        CloseHandle(pipehandle);
        return ret;
    }

    if (!EqualSid(pipeowner, usersid)) {
        err = dupprintf("Owner of named pipe '%s' is not us", pipename);
        ret = new_error_socket(err, plug);
        sfree(err);
        CloseHandle(pipehandle);
        LocalFree(psd);
        return ret;
    }

    LocalFree(psd);

    return make_handle_socket(pipehandle, pipehandle, NULL, plug, TRUE);
}
Beispiel #11
0
/* Move a file handle to recycle bin
 * The pathname must be a valid NT file name generated using filename_to_nt_pathname()
 */
static NTSTATUS move_to_recycle_bin(HANDLE handle, WCHAR *pathname)
{
	IO_STATUS_BLOCK status_block;
	NTSTATUS status;

	/* TODO: Handle the case when recycle bin does not exist (according to cygwin) */
	/* TODO: Handle when the file is inside recycle bin */
	WCHAR recyclepath[512];
	UNICODE_STRING recycle;
	RtlInitEmptyUnicodeString(&recycle, recyclepath, sizeof(recyclepath));
	/* Root directory, should look like "\??\C:\", 7 characters */
	UNICODE_STRING root;
	RtlInitCountedUnicodeString(&root, pathname, sizeof(WCHAR) * 7);
	RtlAppendUnicodeStringToString(&recycle, &root);
	RtlAppendUnicodeToString(&recycle, L"$Recycle.Bin\\");

	WCHAR renamepath[512];
	UNICODE_STRING rename;
	RtlInitEmptyUnicodeString(&rename, renamepath, sizeof(renamepath));
	RtlAppendUnicodeStringToString(&rename, &recycle);
	/* Append user sid */
	{
		WCHAR buf[256];
		UNICODE_STRING sid;
		RtlInitEmptyUnicodeString(&sid, buf, sizeof(buf));
		RtlConvertSidToUnicodeString(&sid, get_user_sid(), FALSE);
		RtlAppendUnicodeStringToString(&rename, &sid);
		RtlAppendUnicodeToString(&rename, L"\\");
	}
	/* Generate an unique file name by append file id and a hash of the pathname,
	 * To allow unlinking multiple hard links of the same file
	 */
	RtlAppendUnicodeToString(&rename, L".flinux");
	/* Append file id */
	{
		FILE_INTERNAL_INFORMATION info;
		status = NtQueryInformationFile(handle, &status_block, &info, sizeof(info), FileInternalInformation);
		if (!NT_SUCCESS(status))
		{
			log_error("NtQueryInformationFile(FileInternalInformation) failed, status: %x", status);
			return status;
		}
		RtlAppendInt64ToString(info.IndexNumber.QuadPart, 16, &rename);
		RtlAppendUnicodeToString(&rename, L"_");
	}
	/* Append file path hash */
	{
		UNICODE_STRING path;
		RtlInitUnicodeString(&path, pathname);
		ULONG hash;
		RtlHashUnicodeString(&path, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &hash);
		RtlAppendIntegerToString(hash, 16, &rename);
	}
	/* Rename file */
	char buf[512];
	FILE_RENAME_INFORMATION *info = (FILE_RENAME_INFORMATION *)buf;
	info->ReplaceIfExists = FALSE;
	info->RootDirectory = NULL;
	info->FileNameLength = rename.Length;
	memcpy(info->FileName, rename.Buffer, rename.Length);
	status = NtSetInformationFile(handle, &status_block, info, sizeof(*info) + info->FileNameLength, FileRenameInformation);
	if (!NT_SUCCESS(status))
	{
		log_error("NtSetInformationFile(FileRenameInformation) failed, status: %x", status);
		return status;
	}
	return STATUS_SUCCESS;
}
Beispiel #12
0
int make_private_security_descriptor(DWORD permissions,
                                     PSECURITY_DESCRIPTOR *psd,
                                     PACL *acl,
                                     char **error)
{
    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
    EXPLICIT_ACCESS ea[3];
    int acl_err;
    int ret = FALSE;

    /* Initialised once, then kept around to reuse forever */
    static PSID worldsid, networksid, usersid;

    *psd = NULL;
    *acl = NULL;
    *error = NULL;

    if (!got_advapi()) {
        *error = dupprintf("unable to load advapi32.dll");
        goto cleanup;
    }

    if (!usersid) {
        if ((usersid = get_user_sid()) == NULL) {
            *error = dupprintf("unable to construct SID for current user: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    if (!worldsid) {
        if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
                                      0, 0, 0, 0, 0, 0, 0, &worldsid)) {
            *error = dupprintf("unable to construct SID for world: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    if (!networksid) {
        if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID,
                                      0, 0, 0, 0, 0, 0, 0, &networksid)) {
            *error = dupprintf("unable to construct SID for "
                               "local same-user access only: %s",
                               win_strerror(GetLastError()));
            goto cleanup;
        }
    }

    memset(ea, 0, sizeof(ea));
    ea[0].grfAccessPermissions = permissions;
    ea[0].grfAccessMode = REVOKE_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.ptstrName = (LPTSTR)worldsid;
    ea[1].grfAccessPermissions = permissions;
    ea[1].grfAccessMode = GRANT_ACCESS;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.ptstrName = (LPTSTR)usersid;
    ea[2].grfAccessPermissions = permissions;
    ea[2].grfAccessMode = REVOKE_ACCESS;
    ea[2].grfInheritance = NO_INHERITANCE;
    ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[2].Trustee.ptstrName = (LPTSTR)networksid;

    acl_err = p_SetEntriesInAclA(3, ea, NULL, acl);
    if (acl_err != ERROR_SUCCESS || *acl == NULL) {
        *error = dupprintf("unable to construct ACL: %s",
                           win_strerror(acl_err));
        goto cleanup;
    }

    *psd = (PSECURITY_DESCRIPTOR)
        LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (!*psd) {
        *error = dupprintf("unable to allocate security descriptor: %s",
                           win_strerror(GetLastError()));
        goto cleanup;
    }

    if (!InitializeSecurityDescriptor(*psd, SECURITY_DESCRIPTOR_REVISION)) {
        *error = dupprintf("unable to initialise security descriptor: %s",
                           win_strerror(GetLastError()));
        goto cleanup;
    }

    if (!SetSecurityDescriptorDacl(*psd, TRUE, *acl, FALSE)) {
        *error = dupprintf("unable to set DACL in security descriptor: %s",
                           win_strerror(GetLastError()));
        goto cleanup;
    }

    ret = TRUE;

  cleanup:
    if (!ret) {
        if (*psd) {
            LocalFree(*psd);
            *psd = NULL;
        }
        if (*acl) {
            LocalFree(*acl);
            *acl = NULL;
        }
    } else {
        sfree(*error);
        *error = NULL;
    }
    return ret;
}