mirror of
https://github.com/samba-team/samba.git
synced 2025-03-11 16:58:40 +03:00
Add LSA RPC 0x2E, lsa_query_info2. Only level implemented is 0x0c, which
is netbios and dns domain info. Also add code to set/fetch the domain GUID from secrets.tdb (although set is not yet called by anyone).
This commit is contained in:
parent
fc0d5479b5
commit
31d7168530
@ -73,6 +73,7 @@
|
||||
#define LSA_RETRPRIVDATA 0x2b
|
||||
#define LSA_OPENPOLICY2 0x2c
|
||||
#define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */
|
||||
#define LSA_QUERYINFO2 0x2e
|
||||
|
||||
/* XXXX these are here to get a compile! */
|
||||
#define LSA_LOOKUPRIDS 0xFD
|
||||
@ -261,6 +262,43 @@ typedef struct lsa_r_query_info
|
||||
|
||||
} LSA_R_QUERY_INFO;
|
||||
|
||||
/* LSA_DNS_DOM_INFO - DNS domain info - info class 12*/
|
||||
typedef struct lsa_dns_dom_info
|
||||
{
|
||||
UNIHDR hdr_nb_dom_name; /* netbios domain name */
|
||||
UNIHDR hdr_dns_dom_name;
|
||||
UNIHDR hdr_forest_name;
|
||||
|
||||
GUID dom_guid; /* domain GUID */
|
||||
|
||||
UNISTR2 uni_nb_dom_name;
|
||||
UNISTR2 uni_dns_dom_name;
|
||||
UNISTR2 uni_forest_name;
|
||||
|
||||
uint32 ptr_dom_sid;
|
||||
DOM_SID2 dom_sid; /* domain SID */
|
||||
} LSA_DNS_DOM_INFO;
|
||||
|
||||
typedef union lsa_info2_union
|
||||
{
|
||||
LSA_DNS_DOM_INFO dns_dom_info;
|
||||
} LSA_INFO2_UNION;
|
||||
|
||||
/* LSA_Q_QUERY_INFO2 - LSA query info */
|
||||
typedef struct lsa_q_query_info2
|
||||
{
|
||||
POLICY_HND pol; /* policy handle */
|
||||
uint16 info_class; /* info class */
|
||||
} LSA_Q_QUERY_INFO2;
|
||||
|
||||
typedef struct lsa_r_query_info2
|
||||
{
|
||||
uint32 ptr; /* pointer to info struct */
|
||||
uint16 info_class;
|
||||
LSA_INFO2_UNION info; /* so far the only one */
|
||||
NTSTATUS status;
|
||||
} LSA_R_QUERY_INFO2;
|
||||
|
||||
/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
|
||||
typedef struct lsa_enum_trust_dom_info
|
||||
{
|
||||
|
@ -35,6 +35,10 @@
|
||||
#define SECRETS_DOMAIN_SID "SECRETS/SID"
|
||||
#define SECRETS_SAM_SID "SAM/SID"
|
||||
|
||||
/* The domain GUID and server GUID (NOT the same) are also not secret */
|
||||
#define SECRETS_DOMAIN_GUID "SECRETS/DOMGUID"
|
||||
#define SECRETS_SERVER_GUID "SECRETS/GUID"
|
||||
|
||||
#define SECRETS_LDAP_BIND_PW "SECRETS/LDAP_BIND_PW"
|
||||
|
||||
/* Authenticated user info is stored in secrets.tdb under these keys */
|
||||
|
@ -128,6 +128,38 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL secrets_store_domain_guid(char *domain, GUID *guid)
|
||||
{
|
||||
fstring key;
|
||||
|
||||
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
||||
strupper(key);
|
||||
return secrets_store(key, guid, sizeof(GUID));
|
||||
}
|
||||
|
||||
BOOL secrets_fetch_domain_guid(char *domain, GUID *guid)
|
||||
{
|
||||
GUID *dyn_guid;
|
||||
fstring key;
|
||||
size_t size;
|
||||
|
||||
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
||||
strupper(key);
|
||||
dyn_guid = (GUID *)secrets_fetch(key, &size);
|
||||
|
||||
if (dyn_guid == NULL)
|
||||
return False;
|
||||
|
||||
if (size != sizeof(GUID))
|
||||
{
|
||||
SAFE_FREE(dyn_guid);
|
||||
return False;
|
||||
}
|
||||
|
||||
*guid = *dyn_guid;
|
||||
SAFE_FREE(dyn_guid);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form a key for fetching the machine trust account password
|
||||
|
@ -3,8 +3,9 @@
|
||||
* RPC Pipe client / server routines
|
||||
* Copyright (C) Andrew Tridgell 1992-1997,
|
||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
|
||||
* Copyright (C) Paul Ashton 1997.
|
||||
* Copyright (C) Andrew Bartlett 2002.
|
||||
* Copyright (C) Paul Ashton 1997,
|
||||
* Copyright (C) Andrew Bartlett 2002,
|
||||
* Copyright (C) Jim McDonough 2002.
|
||||
*
|
||||
* 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
|
||||
@ -2117,3 +2118,108 @@ BOOL policy_handle_is_valid(const POLICY_HND *hnd)
|
||||
ZERO_STRUCT(zero_pol);
|
||||
return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? False : True );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes an LSA_DNS_DOM_INFO structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL lsa_io_dns_dom_info(char *desc, LSA_DNS_DOM_INFO *info,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
prs_debug(ps, depth, desc, "lsa_io_dns_dom_info");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if(!smb_io_unihdr("nb_name", &info->hdr_nb_dom_name, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unihdr("dns_name", &info->hdr_dns_dom_name, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unihdr("forest", &info->hdr_forest_name, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if (!prs_uint8s(False, "dom_guid", ps, depth, info->dom_guid.info, GUID_SIZE))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if(!prs_uint32("dom_sid", ps, depth, &info->ptr_dom_sid))
|
||||
return False;
|
||||
|
||||
if(!smb_io_unistr2("nb_name", &info->uni_nb_dom_name,
|
||||
info->hdr_nb_dom_name.buffer, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unistr2("dns_name", &info->uni_dns_dom_name,
|
||||
info->hdr_dns_dom_name.buffer, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unistr2("forest", &info->uni_forest_name,
|
||||
info->hdr_forest_name.buffer, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes an LSA_Q_QUERY_DNSDOMINFO structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL lsa_io_q_query_info2(char *desc, LSA_Q_QUERY_INFO2 *q_c,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
prs_debug(ps, depth, desc, "lsa_io_q_query_info2");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!smb_io_pol_hnd("pol", &q_c->pol, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_uint16("info_class", ps, depth, &q_c->info_class))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes an LSA_R_QUERY_DNSDOMINFO structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL lsa_io_r_query_info2(char *desc, LSA_R_QUERY_INFO2 *r_c,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
prs_debug(ps, depth, desc, "lsa_io_r_query_info2");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("ptr", ps, depth, &r_c->ptr))
|
||||
return False;
|
||||
if(!prs_uint16("info_class", ps, depth, &r_c->info_class))
|
||||
return False;
|
||||
switch(r_c->info_class) {
|
||||
case 0x000c:
|
||||
if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info,
|
||||
ps, depth))
|
||||
return False;
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n",
|
||||
r_c->info_class));
|
||||
return False;
|
||||
}
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if(!prs_ntstatus("status", ps, depth, &r_c->status))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
@ -3,8 +3,9 @@
|
||||
* RPC Pipe client / server routines
|
||||
* Copyright (C) Andrew Tridgell 1992-1997,
|
||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
|
||||
* Copyright (C) Paul Ashton 1997.
|
||||
* Copyright (C) Jeremy Allison 2001.
|
||||
* Copyright (C) Paul Ashton 1997,
|
||||
* Copyright (C) Jeremy Allison 2001,
|
||||
* Copyright (C) Jim McDonough 2002.
|
||||
*
|
||||
* 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
|
||||
@ -609,6 +610,37 @@ static BOOL api_lsa_query_secobj(pipes_struct *p)
|
||||
return True;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
api_lsa_query_dnsdomainfo
|
||||
***************************************************************************/
|
||||
|
||||
static BOOL api_lsa_query_info2(pipes_struct *p)
|
||||
{
|
||||
LSA_Q_QUERY_INFO2 q_u;
|
||||
LSA_R_QUERY_INFO2 r_u;
|
||||
|
||||
prs_struct *data = &p->in_data.data;
|
||||
prs_struct *rdata = &p->out_data.rdata;
|
||||
|
||||
ZERO_STRUCT(q_u);
|
||||
ZERO_STRUCT(r_u);
|
||||
|
||||
if(!lsa_io_q_query_info2("", &q_u, data, 0)) {
|
||||
DEBUG(0,("api_lsa_query_info2: failed to unmarshall LSA_Q_QUERY_INFO2.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
r_u.status = _lsa_query_info2(p, &q_u, &r_u);
|
||||
|
||||
if (!lsa_io_r_query_info2("", &r_u, rdata, 0)) {
|
||||
DEBUG(0,("api_lsa_query_info2: failed to marshall LSA_R_QUERY_INFO2.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
\PIPE\ntlsa commands
|
||||
***************************************************************************/
|
||||
@ -634,6 +666,7 @@ static struct api_struct api_lsa_cmds[] =
|
||||
{ "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs },
|
||||
{ "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs },
|
||||
{ "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj },
|
||||
{ "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 },
|
||||
{ NULL , 0 , NULL }
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,8 @@
|
||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
|
||||
* Copyright (C) Paul Ashton 1997,
|
||||
* Copyright (C) Jeremy Allison 2001,
|
||||
* Copyright (C) Rafal Szczesniak 2002.
|
||||
* Copyright (C) Rafal Szczesniak 2002,
|
||||
* Copyright (C) Jim McDonough 2002.
|
||||
*
|
||||
* 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
|
||||
@ -341,6 +342,48 @@ static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
init_dns_dom_info.
|
||||
***************************************************************************/
|
||||
static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, char *nb_name,
|
||||
char *dns_name, char *forest_name,
|
||||
GUID *dom_guid, DOM_SID *dom_sid)
|
||||
{
|
||||
if (nb_name && *nb_name) {
|
||||
init_uni_hdr(&r_l->hdr_nb_dom_name, strlen(nb_name));
|
||||
init_unistr2(&r_l->uni_nb_dom_name, nb_name,
|
||||
strlen(nb_name));
|
||||
r_l->hdr_nb_dom_name.uni_max_len += 2;
|
||||
r_l->uni_nb_dom_name.uni_max_len += 1;
|
||||
}
|
||||
|
||||
if (dns_name && *dns_name) {
|
||||
init_uni_hdr(&r_l->hdr_dns_dom_name, strlen(dns_name));
|
||||
init_unistr2(&r_l->uni_dns_dom_name, dns_name,
|
||||
strlen(dns_name));
|
||||
r_l->hdr_dns_dom_name.uni_max_len += 2;
|
||||
r_l->uni_dns_dom_name.uni_max_len += 1;
|
||||
}
|
||||
|
||||
if (forest_name && *forest_name) {
|
||||
init_uni_hdr(&r_l->hdr_forest_name, strlen(forest_name));
|
||||
init_unistr2(&r_l->uni_forest_name, forest_name,
|
||||
strlen(forest_name));
|
||||
r_l->hdr_forest_name.uni_max_len += 2;
|
||||
r_l->uni_forest_name.uni_max_len += 1;
|
||||
}
|
||||
|
||||
/* how do we init the guid ? probably should write an init fn */
|
||||
if (dom_guid) {
|
||||
memcpy(&r_l->dom_guid, dom_guid, sizeof(GUID));
|
||||
}
|
||||
|
||||
if (dom_sid) {
|
||||
r_l->ptr_dom_sid = 1;
|
||||
init_dom_sid2(&r_l->dom_sid, dom_sid);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
_lsa_open_policy2.
|
||||
***************************************************************************/
|
||||
@ -1166,3 +1209,55 @@ NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUER
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
|
||||
{
|
||||
struct lsa_info *handle;
|
||||
char *nb_name = NULL;
|
||||
char *dns_name = NULL;
|
||||
char *forest_name = NULL;
|
||||
DOM_SID *sid = NULL;
|
||||
GUID guid;
|
||||
|
||||
ZERO_STRUCT(guid);
|
||||
r_u->status = NT_STATUS_OK;
|
||||
|
||||
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
|
||||
switch (q_u->info_class) {
|
||||
case 0x0c:
|
||||
/* check if the user have enough rights */
|
||||
if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
/* Request PolicyPrimaryDomainInformation. */
|
||||
switch (lp_server_role()) {
|
||||
case ROLE_DOMAIN_PDC:
|
||||
case ROLE_DOMAIN_BDC:
|
||||
nb_name = global_myworkgroup;
|
||||
/* ugly temp hack for these next two */
|
||||
dns_name = lp_realm();
|
||||
forest_name = lp_realm();
|
||||
sid = get_global_sam_sid();
|
||||
secrets_fetch_domain_guid(global_myworkgroup,
|
||||
&guid);
|
||||
break;
|
||||
default:
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
}
|
||||
init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
|
||||
forest_name,&guid,sid);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
|
||||
r_u->status = NT_STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(r_u->status)) {
|
||||
r_u->ptr = 0x1;
|
||||
r_u->info_class = q_u->info_class;
|
||||
}
|
||||
|
||||
return r_u->status;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user