1
0
mirror of https://github.com/altlinux/admc.git synced 2025-03-22 02:50:30 +03:00

Merge pull request #192 from altlinux/create-gpo-security-descriptor

Create gpo
This commit is contained in:
Dmitry Degtyarev 2021-04-08 13:17:15 +04:00 committed by GitHub
commit ffd4d0ead5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1436 additions and 10 deletions

View File

@ -17,6 +17,7 @@ BuildRequires(pre): qt5-tools-devel
BuildRequires(pre): catch2-devel
BuildRequires(pre): cmake-modules
BuildRequires: samba-devel
BuildRequires: libldap-devel
BuildRequires: libsasl2-devel
BuildRequires: libsmbclient-devel

View File

@ -2,7 +2,7 @@
FROM alt:p9
RUN apt-get update \
&& apt-get install -y qt5-base-devel cmake qt5-tools-devel qt5-tools libuuid-devel libsmbclient-devel libsasl2-devel catch2-devel doxygen glib2-devel libpcre-devel rpm-build gear libldap-devel libcmocka-devel libkrb5-devel \
&& apt-get install -y qt5-base-devel cmake qt5-tools-devel qt5-tools libuuid-devel libsmbclient-devel libsasl2-devel catch2-devel doxygen glib2-devel libpcre-devel rpm-build gear libldap-devel libcmocka-devel libkrb5-devel samba-devel \
&& useradd -ms /bin/bash builder && mkdir /app && chown root:builder /app
# Copies your code file from your action repository to the filesystem path `/` of the container

View File

@ -10,6 +10,9 @@ find_package(Krb5 REQUIRED)
find_package(Ldap REQUIRED)
find_package(Resolv REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(NdrStandard REQUIRED IMPORTED_TARGET ndr_standard)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
@ -21,6 +24,11 @@ add_library(adldap SHARED
ad_display.cpp
ad_filter.cpp
samba/gp_manage.cpp
samba/ndr_security.c
samba/dom_sid.c
samba/replace.c
adldap.qrc
)
@ -35,6 +43,7 @@ target_link_libraries(adldap
Krb5::Krb5
Ldap::Ldap
Resolv::Resolv
PkgConfig::NdrStandard
)
set(TS_FILES

View File

@ -165,6 +165,7 @@ enum SystemFlagsBit {
#define ATTRIBUTE_IP_PHONE "ipPhone"
#define ATTRIBUTE_OTHER_IP_PHONE "otherIpPhone"
#define ATTRIBUTE_UPN_SUFFIXES "uPNSuffixes"
#define ATTRIBUTE_SECURITY_DESCRIPTOR "nTSecurityDescriptor"
#define CLASS_GROUP "group"
#define CLASS_USER "user"

View File

@ -23,6 +23,9 @@
#include "ad_utils.h"
#include "ad_object.h"
#include "ad_display.h"
#include "samba/ndr_security.h"
#include "samba/gp_manage.h"
#include "samba/dom_sid.h"
#include <ldap.h>
#include <lber.h>
@ -961,7 +964,7 @@ bool AdInterface::user_unlock(const QString &dn) {
}
}
bool AdInterface::create_gpo(const QString &display_name) {
bool AdInterface::create_gpo(const QString &display_name, QString &dn_out) {
//
// Generate UUID used for directory and object names
//
@ -1022,6 +1025,7 @@ bool AdInterface::create_gpo(const QString &display_name) {
//
// TODO: add all attributes during creation, need to directly create through ldap then
const QString dn = QString("CN=%1,CN=Policies,CN=System,%2").arg(uuid, d->domain_head);
dn_out = dn;
const bool result_add = object_add(dn, CLASS_GP_CONTAINER);
if (!result_add) {
return false;
@ -1052,7 +1056,62 @@ bool AdInterface::create_gpo(const QString &display_name) {
return false;
}
// TODO: security descriptor. Samba does this: get nTSecurityDescriptor attribute from the gpo object as raw bytes, then sets the security descriptor of the sysvol dir to that value. Currently not doing that, so security descriptor of sysvol dir is the default one, which is ... bad? Not sure. Problem is, libsmbclient only provides a way to set security descriptor using key/value strings, not the raw bytes basically. So to do it that way would need to decode object security descriptor. Samba source has that implemented internally but not exposed as a usable lib. Probably SHOULD set security descriptor because who knows what the default is, what if it's just randomly modifiable by any user. Also, the security descriptor functionality will be needed for "Security" tab in ADMC at some point. So should either implement all of that stuff (it's a lot...) or hopefully find some lib to use (unlikely). On Windows you would just use Microsoft's lib.
//
// Set security descriptor for sysvol dir
//
// First get descriptor of the GPO
const QHash<QString, AdObject> search_results = search(QString(), {ATTRIBUTE_SECURITY_DESCRIPTOR}, SearchScope_Object, dn);
const AdObject object = search_results[dn];
const QByteArray descriptor_bytes = object.get_value(ATTRIBUTE_SECURITY_DESCRIPTOR);
// Transform descriptor bytes into descriptor struct
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
DATA_BLOB blob;
blob.data = (uint8_t *)descriptor_bytes.data();
blob.length = descriptor_bytes.size();
struct ndr_pull *ndr_pull = ndr_pull_init_blob(&blob, tmp_ctx);
struct security_descriptor domain_sd;
ndr_security_pull_security_descriptor(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &domain_sd);
// Create sysvol descriptor from domain descriptor (not
// one to one, some modifications are needed)
struct security_descriptor *sysvol_sd;
gp_create_gpt_security_descriptor(tmp_ctx, &domain_sd, &sysvol_sd);
const QString sysvol_sd_string =
[tmp_ctx, &sysvol_sd]() {
QString out;
out += QString("REVISION:%1,OWNER:%2,GROUP:%3,").arg(QString::number(sysvol_sd->revision), dom_sid_string(tmp_ctx, sysvol_sd->owner_sid), dom_sid_string(tmp_ctx, sysvol_sd->group_sid));
// NOTE: don't need sacl
for (uint32_t i = 0; i < sysvol_sd->dacl->num_aces; i++) {
struct security_ace ace = sysvol_sd->dacl->aces[i];
char access_mask_buffer[100];
snprintf(access_mask_buffer, sizeof(access_mask_buffer), "0x%08x", ace.access_mask);
if (i > 0) {
out += ",";
}
out += QString("ACL:%1:%2/%3/%4").arg(dom_sid_string(tmp_ctx, &ace.trustee), QString::number(ace.type), QString::number(ace.flags), access_mask_buffer);
}
return out;
}();
const QByteArray sysvol_sd_string_bytes = sysvol_sd_string.toUtf8();
const char *sysvol_sd_cstr = sysvol_sd_string_bytes.constData();
// Set descriptor
smbc_setxattr(cstr(main_dir), "", sysvol_sd_cstr, sysvol_sd_string_bytes.size(), 0);
talloc_free(tmp_ctx);
return true;
}

View File

@ -158,7 +158,8 @@ public:
bool user_set_account_option(const QString &dn, AccountOption option, bool set);
bool user_unlock(const QString &dn);
bool create_gpo(const QString &name);
// "dn_out" is set to the dn of created gpo
bool create_gpo(const QString &name, QString &dn_out);
bool delete_gpo(const QString &dn);
QString sysvol_path_to_smb(const QString &sysvol_path) const;

122
src/adldap/samba/dom_sid.c Normal file
View File

@ -0,0 +1,122 @@
/*
Unix SMB/CIFS implementation.
Samba utility functions
Copyright (C) Stefan (metze) Metzmacher 2002-2004
Copyright (C) Andrew Tridgell 1992-2004
Copyright (C) Jeremy Allison 1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
#include "dom_sid.h"
#include "replace.h"
/*
Convert a dom_sid to a string, printing into a buffer. Return the
string length. If it overflows, return the string length that would
result (buflen needs to be +1 for the terminating 0).
*/
static int dom_sid_string_buf(const struct dom_sid *sid, char *buf, int buflen)
{
int i, ofs, ret;
uint64_t ia;
if (!sid) {
return strlcpy(buf, "(NULL SID)", buflen);
}
ia = ((uint64_t)sid->id_auth[5]) +
((uint64_t)sid->id_auth[4] << 8 ) +
((uint64_t)sid->id_auth[3] << 16) +
((uint64_t)sid->id_auth[2] << 24) +
((uint64_t)sid->id_auth[1] << 32) +
((uint64_t)sid->id_auth[0] << 40);
ret = snprintf(buf, buflen, "S-%"PRIu8"-", sid->sid_rev_num);
if (ret < 0) {
return ret;
}
ofs = ret;
if (ia >= UINT32_MAX) {
ret = snprintf(buf+ofs, MAX(buflen-ofs, 0), "0x%"PRIx64, ia);
} else {
ret = snprintf(buf+ofs, MAX(buflen-ofs, 0), "%"PRIu64, ia);
}
if (ret < 0) {
return ret;
}
ofs += ret;
for (i = 0; i < sid->num_auths; i++) {
ret = snprintf(
buf+ofs,
MAX(buflen-ofs, 0),
"-%"PRIu32,
sid->sub_auths[i]);
if (ret < 0) {
return ret;
}
ofs += ret;
}
return ofs;
}
/*
convert a dom_sid to a string
*/
char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
{
char buf[DOM_SID_STR_BUFLEN];
char *result;
int len;
len = dom_sid_string_buf(sid, buf, sizeof(buf));
if ((len < 0) || (len+1 > sizeof(buf))) {
return talloc_strdup(mem_ctx, "(SID ERR)");
}
/*
* Avoid calling strlen (via talloc_strdup), we already have
* the length
*/
result = (char *)talloc_memdup(mem_ctx, buf, len+1);
if (result == NULL) {
return NULL;
}
/*
* beautify the talloc_report output
*/
talloc_set_name_const(result, result);
return result;
}
char *dom_sid_str_buf(const struct dom_sid *sid, struct dom_sid_buf *dst)
{
int ret;
ret = dom_sid_string_buf(sid, dst->buf, sizeof(dst->buf));
if ((ret < 0) || (ret >= sizeof(dst->buf))) {
strlcpy(dst->buf, "(INVALID SID)", sizeof(dst->buf));
}
return dst->buf;
}

View File

@ -0,0 +1,46 @@
/*
* Unix SMB/CIFS implementation.
* Group Policy Object Support
* Copyright (C) Wilco Baan Hofman 2010
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
#ifndef DOM_SID_H
#define DOM_SID_H
#ifdef __cplusplus
extern "C" {
#endif
#include <talloc.h>
#include <util/data_blob.h>
#include <gen_ndr/security.h>
#define DOM_SID_STR_BUFLEN (15*11+25)
char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid);
struct dom_sid_buf { char buf[DOM_SID_STR_BUFLEN]; };
char *dom_sid_str_buf(const struct dom_sid *sid, struct dom_sid_buf *dst);
#ifdef __cplusplus
}
#endif
#endif /* DOM_SID_H */

View File

@ -0,0 +1,269 @@
/*
* Unix SMB/CIFS implementation.
* Group Policy Object Support
* Copyright (C) Wilco Baan Hofman 2010
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private files from samba source.
* Parts of it were removed or edited.
*/
#include "gp_manage.h"
#include "dom_sid.h"
#include <string.h>
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
bool security_descriptor_acl_add(struct security_descriptor *sd,
bool add_to_sacl,
const struct security_ace *ace)
{
struct security_acl *acl = NULL;
if (add_to_sacl) {
acl = sd->sacl;
} else {
acl = sd->dacl;
}
if (acl == NULL) {
acl = talloc(sd, struct security_acl);
if (acl == NULL) {
// return NT_STATUS_NO_MEMORY;
return false;
}
acl->revision = SECURITY_ACL_REVISION_NT4;
acl->size = 0;
acl->num_aces = 0;
acl->aces = NULL;
}
acl->aces = talloc_realloc(acl, acl->aces,
struct security_ace, acl->num_aces+1);
if (acl->aces == NULL) {
// return NT_STATUS_NO_MEMORY;
return false;
}
acl->aces[acl->num_aces] = *ace;
switch (acl->aces[acl->num_aces].type) {
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
acl->revision = SECURITY_ACL_REVISION_ADS;
break;
default:
break;
}
acl->num_aces++;
if (add_to_sacl) {
sd->sacl = acl;
sd->type |= SEC_DESC_SACL_PRESENT;
} else {
sd->dacl = acl;
sd->type |= SEC_DESC_DACL_PRESENT;
}
// return NT_STATUS_OK;
return true;
}
/*
add an ACE to the SACL of a security_descriptor
*/
bool security_descriptor_sacl_add(struct security_descriptor *sd,
const struct security_ace *ace)
{
return security_descriptor_acl_add(sd, true, ace);
}
/*
add an ACE to the DACL of a security_descriptor
*/
bool security_descriptor_dacl_add(struct security_descriptor *sd,
const struct security_ace *ace)
{
return security_descriptor_acl_add(sd, false, ace);
}
uint32_t gp_ads_to_dir_access_mask(uint32_t access_mask)
{
uint32_t fs_mask;
/* Copy the standard access mask */
fs_mask = access_mask & 0x001F0000;
/* When READ_PROP and LIST_CONTENTS are set, read access is granted on the GPT */
if (access_mask & SEC_ADS_READ_PROP && access_mask & SEC_ADS_LIST) {
fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_LIST | SEC_DIR_READ_ATTRIBUTE |
SEC_DIR_READ_EA | SEC_DIR_TRAVERSE;
}
/* When WRITE_PROP is set, full write access is granted on the GPT */
if (access_mask & SEC_ADS_WRITE_PROP) {
fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_WRITE_ATTRIBUTE |
SEC_DIR_WRITE_EA | SEC_DIR_ADD_FILE |
SEC_DIR_ADD_SUBDIR;
}
/* Map CREATE_CHILD to add file and add subdir */
if (access_mask & SEC_ADS_CREATE_CHILD)
fs_mask |= SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR;
/* Map ADS delete child to dir delete child */
if (access_mask & SEC_ADS_DELETE_CHILD)
fs_mask |= SEC_DIR_DELETE_CHILD;
return fs_mask;
}
struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
const struct security_acl *oacl)
{
struct security_acl *nacl;
if (oacl == NULL) {
return NULL;
}
if (oacl->aces == NULL && oacl->num_aces > 0) {
return NULL;
}
nacl = talloc (mem_ctx, struct security_acl);
if (nacl == NULL) {
return NULL;
}
*nacl = (struct security_acl) {
.revision = oacl->revision,
.size = oacl->size,
.num_aces = oacl->num_aces,
};
if (nacl->num_aces == 0) {
return nacl;
}
nacl->aces = (struct security_ace *)talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces);
if (nacl->aces == NULL) {
goto failed;
}
return nacl;
failed:
talloc_free (nacl);
return NULL;
}
bool gp_create_gpt_security_descriptor(TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret) {
struct security_descriptor *fs_sd;
// uint32_t i;
/* Allocate the file system security descriptor */
fs_sd = talloc(mem_ctx, struct security_descriptor);
// NT_STATUS_HAVE_NO_MEMORY(fs_sd);
/* Copy the basic information from the directory server security descriptor */
fs_sd->owner_sid = (dom_sid *) talloc_memdup(fs_sd, ds_sd->owner_sid, sizeof(struct dom_sid));
if (fs_sd->owner_sid == NULL) {
TALLOC_FREE(fs_sd);
// return NT_STATUS_NO_MEMORY;
return false;
}
fs_sd->group_sid = (dom_sid *) talloc_memdup(fs_sd, ds_sd->group_sid, sizeof(struct dom_sid));
if (fs_sd->group_sid == NULL) {
TALLOC_FREE(fs_sd);
// return NT_STATUS_NO_MEMORY;
return false;
}
fs_sd->type = ds_sd->type;
fs_sd->revision = ds_sd->revision;
/* Copy the sacl */
fs_sd->sacl = security_acl_dup(fs_sd, ds_sd->sacl);
if (fs_sd->sacl == NULL) {
TALLOC_FREE(fs_sd);
// return NT_STATUS_NO_MEMORY;
return false;
}
/* Copy the dacl */
fs_sd->dacl = talloc_zero(fs_sd, struct security_acl);
if (fs_sd->dacl == NULL) {
TALLOC_FREE(fs_sd);
// return NT_STATUS_NO_MEMORY;
return false;
}
for (uint32_t i = 0; i < ds_sd->dacl->num_aces; i++) {
const char *trustee = dom_sid_string(fs_sd, &ds_sd->dacl->aces[i].trustee);
struct security_ace *ace;
/* Don't add the allow for SID_BUILTIN_PREW2K */
if (!(ds_sd->dacl->aces[i].type & SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) && strcmp(trustee, SID_BUILTIN_PREW2K) == 0) {
talloc_free((void *) trustee);
continue;
}
/* Copy the ace from the directory server security descriptor */
ace = (security_ace *) talloc_memdup(fs_sd, &ds_sd->dacl->aces[i], sizeof(struct security_ace));
if (ace == NULL) {
TALLOC_FREE(fs_sd);
// return NT_STATUS_NO_MEMORY;
return false;
}
/* Set specific inheritance flags for within the GPO */
ace->flags |= SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT;
if (strcmp(trustee, SID_CREATOR_OWNER) == 0) {
ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
}
/* Get a directory access mask from the assigned access mask on the LDAP object */
ace->access_mask = gp_ads_to_dir_access_mask(ace->access_mask);
/* Add the ace to the security descriptor DACL */
const bool dacl_add_success = security_descriptor_dacl_add(fs_sd, ace);
if (!dacl_add_success) {
// if (!NT_STATUS_IS_OK(status)) {
// DEBUG(0, ("Failed to add a dacl to file system security descriptor\n"));
// return status;
return false;
}
/* Clean up the allocated data in this iteration */
talloc_free((void *) trustee);
}
*ret = fs_sd;
return true;
}

View File

@ -0,0 +1,38 @@
/*
* Unix SMB/CIFS implementation.
* Group Policy Object Support
* Copyright (C) Wilco Baan Hofman 2010
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
#ifndef GP_MANAGE_H
#define GP_MANAGE_H
extern "C" {
#include <ndr.h>
#include <gen_ndr/security.h>
#include <talloc.h>
};
bool gp_create_gpt_security_descriptor(TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret);
#endif /* GP_MANAGE_H */

View File

@ -0,0 +1,525 @@
/*
* Unix SMB/CIFS implementation.
* Group Policy Object Support
* Copyright (C) Wilco Baan Hofman 2010
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
// #include "util/util.h"
#include <ndr.h>
#include <gen_ndr/security.h>
#include <string.h>
#ifndef N_ELEMENTS
#define N_ELEMENTS(arr) (sizeof(arr) / sizeof(arr[0]))
#endif
// TODO: figure out how to define this
#define SMB_HAS_NEW_NDR_PULL_STEAL_SWITCH
static enum ndr_err_code
ndr_pull_GUID(struct ndr_pull *ndr,
int ndr_flags,
struct GUID *r)
{
uint32_t size_clock_seq_0 = 0;
uint32_t size_node_0 = 0;
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time_low));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_mid));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_hi_and_version));
size_clock_seq_0 = 2;
NDR_CHECK(ndr_pull_array_uint8(ndr,
NDR_SCALARS,
r->clock_seq,
size_clock_seq_0));
size_node_0 = 6;
NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->node, size_node_0));
NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
}
if (ndr_flags & NDR_BUFFERS) {
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace_flags(struct ndr_pull *ndr,
int ndr_flags,
uint8_t *r)
{
uint8_t v;
NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &v));
*r = v;
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace_type(struct ndr_pull *ndr,
int ndr_flags,
enum security_ace_type *r)
{
uint8_t v;
NDR_CHECK(ndr_pull_enum_uint8(ndr, ndr_flags, &v));
*r = v;
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace_object_flags(struct ndr_pull *ndr,
int ndr_flags,
uint32_t *r)
{
uint32_t v;
NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &v));
*r = v;
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace_object_type(struct ndr_pull *ndr,
int ndr_flags,
union security_ace_object_type *r)
{
uint32_t level;
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
/* This token is not used again (except perhaps below in the NDR_BUFFERS case) */
#ifdef SMB_HAS_NEW_NDR_PULL_STEAL_SWITCH
NDR_CHECK(ndr_pull_steal_switch_value(ndr, r, &level));
#else
level = ndr_pull_steal_switch_value(ndr, r);
#endif
NDR_CHECK(ndr_pull_union_align(ndr, 4));
switch (level) {
case SEC_ACE_OBJECT_TYPE_PRESENT: {
NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->type));
break; }
default: {
break; }
}
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace_object_inherited_type(struct ndr_pull *ndr,
int ndr_flags,
union security_ace_object_inherited_type *r)
{
uint32_t level;
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
/* This token is not used again (except perhaps below in the NDR_BUFFERS case) */
#ifdef SMB_HAS_NEW_NDR_PULL_STEAL_SWITCH
NDR_CHECK(ndr_pull_steal_switch_value(ndr, r, &level));
#else
level = ndr_pull_steal_switch_value(ndr, r);
#endif
NDR_CHECK(ndr_pull_union_align(ndr, 4));
switch (level) {
case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: {
NDR_CHECK(ndr_pull_GUID(ndr,
NDR_SCALARS,
&r->inherited_type));
break; }
default: {
break; }
}
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace_object(struct ndr_pull *ndr,
int ndr_flags,
struct security_ace_object *r)
{
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_security_ace_object_flags
(ndr, NDR_SCALARS, &r->flags));
NDR_CHECK(ndr_pull_set_switch_value
(ndr, &r->type, r->flags & SEC_ACE_OBJECT_TYPE_PRESENT));
NDR_CHECK(ndr_pull_security_ace_object_type
(ndr, NDR_SCALARS, &r->type));
NDR_CHECK(ndr_pull_set_switch_value
(ndr,
&r->inherited_type,
r->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT));
NDR_CHECK(ndr_pull_security_ace_object_inherited_type
(ndr, NDR_SCALARS, &r->inherited_type));
NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_pull_set_switch_value
(ndr,
&r->type,
r->flags & SEC_ACE_OBJECT_TYPE_PRESENT));
NDR_CHECK(ndr_pull_security_ace_object_type
(ndr, NDR_BUFFERS, &r->type));
NDR_CHECK(ndr_pull_set_switch_value
(ndr,
&r->inherited_type,
r->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT));
NDR_CHECK(ndr_pull_security_ace_object_inherited_type
(ndr, NDR_BUFFERS, &r->inherited_type));
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr,
int ndr_flags,
union security_ace_object_ctr *r)
{
uint32_t level;
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
/* This token is not used again (except perhaps below in the NDR_BUFFERS case) */
#ifdef SMB_HAS_NEW_NDR_PULL_STEAL_SWITCH
NDR_CHECK(ndr_pull_steal_switch_value(ndr, r, &level));
#else
level = ndr_pull_steal_switch_value(ndr, r);
#endif
NDR_CHECK(ndr_pull_union_align(ndr, 4));
switch (level) {
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: {
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_SCALARS, &r->object));
break; }
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: {
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_SCALARS, &r->object));
break; }
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: {
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_SCALARS, &r->object));
break; }
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: {
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_SCALARS, &r->object));
break; }
default: {
break; }
}
}
if (ndr_flags & NDR_BUFFERS) {
if (!(ndr_flags & NDR_SCALARS)) {
/* We didn't get it above, and the token is not needed after this. */
#ifdef SMB_HAS_NEW_NDR_PULL_STEAL_SWITCH
NDR_CHECK(ndr_pull_steal_switch_value(ndr, r, &level));
#else
level = ndr_pull_steal_switch_value(ndr, r);
#endif
}
switch (level) {
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_BUFFERS, &r->object));
break;
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_BUFFERS, &r->object));
break;
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_BUFFERS, &r->object));
break;
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
NDR_CHECK(ndr_pull_security_ace_object
(ndr, NDR_BUFFERS, &r->object));
break;
default:
break;
}
}
return NDR_ERR_SUCCESS;
}
enum ndr_err_code
ndr_pull_dom_sid(struct ndr_pull *ndr,
int ndr_flags,
struct dom_sid *r)
{
uint32_t cntr_sub_auths_0;
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num));
NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths));
if (r->num_auths < 0 || r->num_auths > N_ELEMENTS(r->sub_auths)) {
return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
}
NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
memset(&r->sub_auths, 0, sizeof(r->sub_auths));
for (cntr_sub_auths_0 = 0;
cntr_sub_auths_0 < r->num_auths;
cntr_sub_auths_0++) {
NDR_CHECK(ndr_pull_uint32
(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0]));
}
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_ace(struct ndr_pull *ndr,
int ndr_flags,
struct security_ace *r)
{
if (ndr_flags & NDR_SCALARS) {
uint32_t start_ofs = ndr->offset;
uint32_t size = 0;
uint32_t pad = 0;
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask));
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
NDR_CHECK(ndr_pull_security_ace_object_ctr
(ndr, NDR_SCALARS, &r->object));
NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
size = ndr->offset - start_ofs;
if (r->size < size) {
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
"ndr_pull_security_ace: r->size %u < size %u",
(unsigned)r->size, size);
}
pad = r->size - size;
NDR_PULL_NEED_BYTES(ndr, pad);
ndr->offset += pad;
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
NDR_CHECK(ndr_pull_security_ace_object_ctr
(ndr, NDR_BUFFERS, &r->object));
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_acl_revision(struct ndr_pull *ndr,
int ndr_flags,
enum security_acl_revision *r)
{
uint16_t v;
NDR_CHECK(ndr_pull_enum_uint1632(ndr, ndr_flags, &v));
*r = v;
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_acl(struct ndr_pull *ndr,
int ndr_flags,
struct security_acl *r)
{
uint32_t size_aces_0 = 0;
uint32_t cntr_aces_0;
TALLOC_CTX *_mem_save_aces_0;
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_security_acl_revision
(ndr, NDR_SCALARS, &r->revision));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_aces));
if (r->num_aces > 2000) {
return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
}
size_aces_0 = r->num_aces;
NDR_PULL_ALLOC_N(ndr, r->aces, size_aces_0);
_mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0);
for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) {
NDR_CHECK(ndr_pull_security_ace
(ndr, NDR_SCALARS, &r->aces[cntr_aces_0]));
}
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0);
NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
}
if (ndr_flags & NDR_BUFFERS) {
size_aces_0 = r->num_aces;
_mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0);
for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) {
NDR_CHECK(ndr_pull_security_ace
(ndr, NDR_BUFFERS, &r->aces[cntr_aces_0]));
}
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0);
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_descriptor_revision(struct ndr_pull *ndr,
int ndr_flags,
enum security_descriptor_revision *r)
{
uint8_t v;
NDR_CHECK(ndr_pull_enum_uint8(ndr, ndr_flags, &v));
*r = v;
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code
ndr_pull_security_descriptor_type(struct ndr_pull *ndr,
int ndr_flags,
uint16_t *r)
{
uint16_t v;
NDR_CHECK(ndr_pull_uint16(ndr, ndr_flags, &v));
*r = v;
return NDR_ERR_SUCCESS;
}
enum ndr_err_code
ndr_security_pull_security_descriptor(struct ndr_pull *ndr,
int ndr_flags,
struct security_descriptor *r)
{
uint32_t _ptr_owner_sid;
TALLOC_CTX *_mem_save_owner_sid_0;
uint32_t _ptr_group_sid;
TALLOC_CTX *_mem_save_group_sid_0;
uint32_t _ptr_sacl;
TALLOC_CTX *_mem_save_sacl_0;
uint32_t _ptr_dacl;
TALLOC_CTX *_mem_save_dacl_0;
{
uint32_t _flags_save_STRUCT = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN);
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 5));
NDR_CHECK(ndr_pull_security_descriptor_revision(ndr,
NDR_SCALARS,
&r->revision));
NDR_CHECK(ndr_pull_security_descriptor_type(ndr,
NDR_SCALARS,
&r->type));
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_owner_sid));
if (_ptr_owner_sid) {
NDR_PULL_ALLOC(ndr, r->owner_sid);
NDR_CHECK(ndr_pull_relative_ptr1(ndr,
r->owner_sid,
_ptr_owner_sid));
} else {
r->owner_sid = NULL;
}
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_sid));
if (_ptr_group_sid) {
NDR_PULL_ALLOC(ndr, r->group_sid);
NDR_CHECK(ndr_pull_relative_ptr1(ndr,
r->group_sid,
_ptr_group_sid));
} else {
r->group_sid = NULL;
}
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sacl));
if (_ptr_sacl) {
NDR_PULL_ALLOC(ndr, r->sacl);
NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->sacl, _ptr_sacl));
} else {
r->sacl = NULL;
}
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_dacl));
if (_ptr_dacl) {
NDR_PULL_ALLOC(ndr, r->dacl);
NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->dacl, _ptr_dacl));
} else {
r->dacl = NULL;
}
NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->owner_sid) {
uint32_t _relative_save_offset;
_relative_save_offset = ndr->offset;
NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->owner_sid));
_mem_save_owner_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->owner_sid, 0);
NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->owner_sid));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_owner_sid_0, 0);
if (ndr->offset > ndr->relative_highest_offset) {
ndr->relative_highest_offset = ndr->offset;
}
ndr->offset = _relative_save_offset;
}
if (r->group_sid) {
uint32_t _relative_save_offset;
_relative_save_offset = ndr->offset;
NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->group_sid));
_mem_save_group_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->group_sid, 0);
NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->group_sid));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_sid_0, 0);
if (ndr->offset > ndr->relative_highest_offset) {
ndr->relative_highest_offset = ndr->offset;
}
ndr->offset = _relative_save_offset;
}
if (r->sacl) {
uint32_t _relative_save_offset;
_relative_save_offset = ndr->offset;
NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->sacl));
_mem_save_sacl_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->sacl, 0);
NDR_CHECK(ndr_pull_security_acl(ndr,
NDR_SCALARS|NDR_BUFFERS,
r->sacl));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sacl_0, 0);
if (ndr->offset > ndr->relative_highest_offset) {
ndr->relative_highest_offset = ndr->offset;
}
ndr->offset = _relative_save_offset;
}
if (r->dacl) {
uint32_t _relative_save_offset;
_relative_save_offset = ndr->offset;
NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->dacl));
_mem_save_dacl_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->dacl, 0);
NDR_CHECK(ndr_pull_security_acl(ndr,
NDR_SCALARS|NDR_BUFFERS,
r->dacl));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_dacl_0, 0);
if (ndr->offset > ndr->relative_highest_offset) {
ndr->relative_highest_offset = ndr->offset;
}
ndr->offset = _relative_save_offset;
}
}
ndr->flags = _flags_save_STRUCT;
}
return NDR_ERR_SUCCESS;
}

View File

@ -0,0 +1,44 @@
/*
* Unix SMB/CIFS implementation.
* Group Policy Object Support
* Copyright (C) Wilco Baan Hofman 2010
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
#ifndef NDR_SECURITY_H
#define NDR_SECURITY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <ndr.h>
#include <gen_ndr/security.h>
enum ndr_err_code
ndr_security_pull_security_descriptor(struct ndr_pull *ndr,
int ndr_flags,
struct security_descriptor *r);
#ifdef __cplusplus
}
#endif
#endif /* NDR_SECURITY_H */

View File

@ -0,0 +1,54 @@
/*
Unix SMB/CIFS implementation.
replacement routines for broken systems
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jelmer Vernooij 2005-2008
Copyright (C) Matthieu Patou 2010
** NOTE! The following LGPL license applies to the replace
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
#include "replace.h"
#include <string.h>
/*
* Like strncpy but does not 0 fill the buffer and always null
* terminates. bufsize is the size of the destination buffer.
* Returns the length of s.
*/
size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len = strlen(s);
size_t ret = len;
if (bufsize <= 0) {
return 0;
}
if (len >= bufsize) {
len = bufsize - 1;
}
memcpy(d, s, len);
d[len] = 0;
return ret;
}

View File

@ -0,0 +1,71 @@
/*
Unix SMB/CIFS implementation.
macros to go along with the lib/replace/ portability layer code
Copyright (C) Andrew Tridgell 2005
Copyright (C) Jelmer Vernooij 2006-2008
Copyright (C) Jeremy Allison 2007.
** NOTE! The following LGPL license applies to the replace
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is a copy of private samba sources. Parts of it
* were removed or edited.
*/
#ifndef _LIBREPLACE_REPLACE_H
#define _LIBREPLACE_REPLACE_H
#include <stddef.h>
#include <inttypes.h>
#ifndef __PRI64_PREFIX
# if __WORDSIZE == 64 && ! defined __APPLE__
# define __PRI64_PREFIX "l"
# else
# define __PRI64_PREFIX "ll"
# endif
#endif
#ifndef PRIu8
# define PRIu8 "u"
#endif
#ifndef PRIu16
# define PRIu16 "u"
#endif
#ifndef PRIu32
# define PRIu32 "u"
#endif
#ifndef PRIu64
# define PRIu64 __PRI64_PREFIX "u"
#endif
#define strlcpy rep_strlcpy
size_t rep_strlcpy(char *d, const char *s, size_t bufsize);
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#endif /* _LIBREPLACE_REPLACE_H */

View File

@ -47,6 +47,7 @@ add_executable(admc
about_dialog.cpp
manual_dialog.cpp
select_policy_dialog.cpp
create_policy_dialog.cpp
gplink.cpp
filter_widget/filter_widget.cpp

View File

@ -32,6 +32,7 @@
#include "status.h"
#include "rename_dialog.h"
#include "create_dialog.h"
#include "create_policy_dialog.h"
#include "move_dialog.h"
#include "find_dialog.h"
#include "password_dialog.h"
@ -263,12 +264,7 @@ void CentralWidget::go_online(AdInterface &ad) {
const QHash<QString, AdObject> search_results = ad.search(filter, search_attributes, SearchScope_All);
for (const AdObject &object : search_results.values()) {
QStandardItem *scope_item;
QList<QStandardItem *> results_row;
console_widget->add_buddy_scope_and_results(policy_links_results_id, ScopeNodeType_Static, policies_item->index(), &scope_item, &results_row);
setup_policy_scope_item(scope_item, object);
setup_policy_results_row(results_row, object);
add_policy_to_console(object);
}
console_widget->sort_scope();
@ -481,6 +477,30 @@ void CentralWidget::edit_upn_suffixes() {
void CentralWidget::create_policy() {
// TODO: implement using ad.create_gpo() (which is
// unfinished)
auto dialog = new CreatePolicyDialog(this);
connect(
dialog, &QDialog::accepted,
[this, dialog]() {
AdInterface ad;
if (ad_failed(ad)) {
return;
}
const QString dn = dialog->get_created_dn();
const QList<QString> search_attributes = policy_model_search_attributes();
const QHash<QString, AdObject> search_results = ad.search(QString(), search_attributes, SearchScope_Object, dn);
const AdObject object = search_results[dn];
add_policy_to_console(object);
// NOTE: not adding policy object to the domain
// tree, but i think it's ok?
});
dialog->open();
}
void CentralWidget::add_link() {
@ -1102,3 +1122,12 @@ QList<QString> CentralWidget::get_selected_dns() {
return selected.keys();
}
void CentralWidget::add_policy_to_console(const AdObject &object) {
QStandardItem *scope_item;
QList<QStandardItem *> results_row;
console_widget->add_buddy_scope_and_results(policy_links_results_id, ScopeNodeType_Static, policies_index, &scope_item, &results_row);
setup_policy_scope_item(scope_item, object);
setup_policy_results_row(results_row, object);
}

View File

@ -131,6 +131,7 @@ private:
void create_helper(const QString &object_class);
QHash<QString, QPersistentModelIndex> get_selected_dns_and_indexes();
QList<QString> get_selected_dns();
void add_policy_to_console(const AdObject &object);
};
#endif /* CENTRAL_WIDGET_H */

View File

@ -0,0 +1,104 @@
/*
* ADMC - AD Management Center
*
* Copyright (C) 2020 BaseALT Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "create_policy_dialog.h"
#include "adldap.h"
#include "status.h"
#include <QLineEdit>
#include <QFormLayout>
#include <QPushButton>
#include <QMessageBox>
// TODO: implement checkbox for account option "User cannot change password". Can't just do it through UAC attribute bits.
// TODO: not sure about how required_edits are done, maybe
// just do this through verify()? Had to remove upnedit from
// required_edits because that's a list of stringedits. Now upnedit checks that it's not empty in verify();
CreatePolicyDialog::CreatePolicyDialog(QWidget *parent)
: QDialog(parent)
{
setAttribute(Qt::WA_DeleteOnClose);
setMinimumWidth(400);
const auto title = QString(tr("Create GPO"));
setWindowTitle(title);
name_edit = new QLineEdit();
name_edit->setText("New Group Policy Object");
const auto edits_layout = new QFormLayout();
edits_layout->addRow(tr("Name"), name_edit);
auto create_button = new QPushButton(tr("Create"));
const auto layout = new QVBoxLayout();
setLayout(layout);
layout->addLayout(edits_layout);
layout->addWidget(create_button);
connect(
create_button, &QAbstractButton::clicked,
this, &CreatePolicyDialog::accept);
}
QString CreatePolicyDialog::get_created_dn() const {
return created_dn;
}
void CreatePolicyDialog::accept() {
AdInterface ad;
if (ad_failed(ad)) {
return;
}
show_busy_indicator();
const QString name = name_edit->text();
// NOTE: since this is *display name*, not just name,
// have to manually check for conflict. Server wouldn't
// catch this.
const bool name_conflict =
[&]() {
const QString filter = filter_CONDITION(Condition_Equals, ATTRIBUTE_DISPLAY_NAME, name);
const QHash<QString, AdObject> results = ad.search(filter, QList<QString>(), SearchScope_All);
return !results.isEmpty();
}();
if (name_conflict) {
QMessageBox::warning(this, tr("Error"), tr("Group Policy Object with this name already exists."));
return;
}
const bool success = ad.create_gpo(name, created_dn);
hide_busy_indicator();
STATUS()->display_ad_messages(ad, this);
if (success) {
QDialog::accept();
}
}

View File

@ -0,0 +1,50 @@
/*
* ADMC - AD Management Center
*
* Copyright (C) 2020 BaseALT Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CREATE_POLICY_DIALOG_H
#define CREATE_POLICY_DIALOG_H
/**
* Creates a GPO.
*/
#include <QDialog>
#include <QString>
#include <QList>
class QLineEdit;
class CreatePolicyDialog : public QDialog {
Q_OBJECT
public:
CreatePolicyDialog(QWidget *parent);
QString get_created_dn() const;
public slots:
void accept();
private:
QLineEdit *name_edit;
QString created_dn;
};
#endif /* CREATE_POLICY_DIALOG_H */

View File

@ -53,6 +53,7 @@ set(TEST_SOURCES
${PROJECT_SOURCE_DIR}/src/admc/about_dialog.cpp
${PROJECT_SOURCE_DIR}/src/admc/manual_dialog.cpp
${PROJECT_SOURCE_DIR}/src/admc/select_policy_dialog.cpp
${PROJECT_SOURCE_DIR}/src/admc/create_policy_dialog.cpp
${PROJECT_SOURCE_DIR}/src/admc/gplink.cpp
${PROJECT_SOURCE_DIR}/src/admc/filter_widget/filter_widget.cpp