Update of /cvsroot/pywin32/pywin32/win32/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17051/win32/src
Modified Files:
win32security.i win32security_sspi.cpp win32security_sspi.h
Added Files:
win32security_ds.cpp
Log Message:
* setup.py now allows sources to be specified; win32security and win32net
now do so, making their .dsp files redundant.
* Existing win32security Ds* (DirectoryService) functions (not to be
confused with the COM related win32com.adsi module!) split into
new win32security_ds.cpp module.
* New win32security functions TranslateName, DsGetDcName and DsCrackNames
* Release the GIL when calling SSPI and DS functions.
* New Ds related constants in ntsecuritycon.
* New tests for these functions.
--- NEW FILE: win32security_ds.cpp ---
#include "PyWinTypes.h"
#include "structmember.h"
#include "PyWinObjects.h"
#include "PySecurityObjects.h"
#include "win32security_sspi.h"
#include "Lm.h" // for NetApiBufferFree, for some Ds functions.
// Directory service handle, yet another type of PyHANDLE
// @object PyDS_HANDLE|Directory service handle, returned by <om win32security.DsBind>
// Subtype of <o PyHANDLE>, inherits all properties and methods
class PyDS_HANDLE: public PyHANDLE
{
public:
PyDS_HANDLE(HANDLE hInit) : PyHANDLE(hInit) {}
virtual BOOL Close(void) {
DWORD err;
if (!m_handle)
return TRUE; // already closed or Detached, nothing to do
if (pfnDsUnBind==NULL){
// should not happen if functions to create a Ds handle exist ...
PyErr_SetString(PyExc_SystemError,"Error closing PyDS_HANDLE, DsUnBind is NULL");
return FALSE;
}
err = (*pfnDsUnBind)(&m_handle);
// ??? This function apparently never returns an error, no matter what you pass to it ???
if (err==NO_ERROR){
m_handle = 0;
return TRUE;
}
PyWin_SetAPIError("PyDS_HANDLE::Close", err);
return FALSE;
}
virtual const char *GetTypeName(){
return "PyDS_HANDLE";
}
};
// directory service functions for registering target Spns to be used with Kerberos
extern PyObject *PyDsBind(PyObject *self, PyObject *args)
{
WCHAR *dc=NULL, *domain=NULL;
PyObject *obdc=Py_None, *obdomain=Py_None;
PyObject *ret=NULL;
DWORD err;
HANDLE dshandle;
CHECK_PFN(DsBind);
if (!PyArg_ParseTuple(args, "|OO:DsBind", obdc, obdomain))
return NULL;
if (PyWinObject_AsWCHAR(obdc, &dc, TRUE) &&
PyWinObject_AsWCHAR(obdomain, &domain, TRUE)){
err=(*pfnDsBind)(dc, domain, &dshandle);
if (err==NO_ERROR)
ret=new PyDS_HANDLE(dshandle);
else
PyWin_SetAPIError("DsBind",err);
}
PyWinObject_FreeWCHAR(dc);
PyWinObject_FreeWCHAR(domain);
return ret;
}
extern PyObject *PyDsUnBind(PyObject *self, PyObject *args)
{
DWORD err;
HANDLE dshandle;
PyObject *obhandle;
CHECK_PFN(DsUnBind);
if (!PyArg_ParseTuple(args, "O:DsUnBind", &obhandle))
return NULL;
if (!PyWinObject_AsHANDLE(obhandle, &dshandle))
return NULL;
Py_BEGIN_ALLOW_THREADS
err=(*pfnDsUnBind)(&dshandle);
Py_END_ALLOW_THREADS
if (err==NO_ERROR){
Py_INCREF(Py_None);
return Py_None;
}
PyWin_SetAPIError("DsUnBind",err);
return NULL;
}
void PyWinObject_FreeWCHARArray(LPWSTR *wchars, DWORD str_cnt)
{
if (wchars!=NULL){
for (DWORD wchar_index=0; wchar_index<str_cnt; wchar_index++)
PyWinObject_FreeWCHAR(wchars[wchar_index]);
free(wchars);
}
}
BOOL PyWinObject_AsWCHARArray(PyObject *str_seq, LPWSTR **wchars, DWORD *str_cnt)
{
BOOL ret=FALSE;
PyObject *str_tuple=NULL, *tuple_item;
DWORD bufsize, tuple_index;
*wchars=NULL;
*str_cnt=0;
if ((str_tuple=PySequence_Tuple(str_seq))==NULL)
return FALSE;
*str_cnt=PyTuple_Size(str_tuple);
bufsize=*str_cnt * sizeof(LPWSTR);
*wchars=(LPWSTR *)malloc(bufsize);
if (*wchars==NULL){
PyErr_Format(PyExc_MemoryError, "Unable to allocate %d bytes", bufsize);
goto done;
}
ZeroMemory(*wchars, bufsize);
for (tuple_index=0;tuple_index<*str_cnt;tuple_index++){
tuple_item=PyTuple_GET_ITEM(str_tuple, tuple_index);
if (!PyWinObject_AsWCHAR(tuple_item, &((*wchars)[tuple_index]), FALSE)){
PyWinObject_FreeWCHARArray(*wchars, *str_cnt);
*wchars=NULL;
*str_cnt=0;
goto done;
}
}
ret=TRUE;
done:
Py_XDECREF(str_tuple);
return ret;
}
extern PyObject *PyDsGetSpn(PyObject *self, PyObject *args)
{
DWORD err, cSpns, bufsize, name_cnt;
DS_SPN_NAME_TYPE ServiceType;
WCHAR *ServiceClass=NULL, *ServiceName=NULL;
PyObject *obServiceClass, *obServiceName;
PyObject *ret=NULL, *tuple_item;
LPWSTR *Spns=NULL, *InstanceNames=NULL;
USHORT tuple_index, InstancePort=0, cInstanceNames=0, *InstancePorts=NULL;
long port_nbr;
PyObject *obInstanceNames=Py_None, *obInstancePorts=Py_None;
PyObject *obInstancePorts_tuple=NULL;
CHECK_PFN(DsGetSpn);
CHECK_PFN(DsFreeSpnArray);
if (!PyArg_ParseTuple(args,"lOO|HOO:DsGetSpn", &ServiceType, &obServiceClass, &obServiceName,
&InstancePort, &obInstanceNames, &obInstancePorts))
return NULL;
if (!PyWinObject_AsWCHAR(obServiceClass, &ServiceClass, FALSE))
goto done;
if (!PyWinObject_AsWCHAR(obServiceName, &ServiceName, TRUE))
goto done;
if (obInstanceNames!=Py_None){
if (!PyWinObject_AsWCHARArray(obInstanceNames, &InstanceNames, &name_cnt))
goto done;
if (name_cnt>USHRT_MAX){
PyErr_Format(PyExc_ValueError, "Count of InstanceNames cannot exceed %d", USHRT_MAX);
goto done;
}
cInstanceNames=(USHORT)name_cnt;
}
if (obInstancePorts!=Py_None){
if ((obInstancePorts_tuple=PySequence_Tuple(obInstancePorts))==NULL)
goto done;
if (PyTuple_Size(obInstancePorts_tuple)!=cInstanceNames){
PyErr_SetString(PyExc_ValueError,"DsGetSpn: InstancePorts must be same size sequence as InstanceNames");
goto done;
}
bufsize=cInstanceNames * sizeof(USHORT);
InstancePorts=(USHORT *)malloc(bufsize);
if (InstancePorts==NULL){
PyErr_Format(PyExc_MemoryError, "DsGetSpn: Unable to allocate %d bytes", bufsize);
goto done;
}
for (tuple_index=0;tuple_index<cInstanceNames;tuple_index++){
tuple_item=PyTuple_GET_ITEM(obInstancePorts_tuple,tuple_index);
// convert a python int to a USHORT
// ??? any API function to do this other than H format of PyArg_ParseTuple ???
port_nbr=PyInt_AsLong(tuple_item);
if ((port_nbr==(unsigned long)-1 && PyErr_Occurred()) || (port_nbr<0)){
PyErr_Clear();
PyErr_Format(PyExc_TypeError,"InstancePorts must be a sequence of ints in the range 0-%d",USHRT_MAX);
goto done;
}
if (port_nbr > USHRT_MAX){
PyErr_Format(PyExc_ValueError, "InstancePorts values cannot exceed %d", USHRT_MAX);
goto done;
}
InstancePorts[tuple_index]=(USHORT)port_nbr;
}
}
Py_BEGIN_ALLOW_THREADS
err=(*pfnDsGetSpn)(ServiceType, ServiceClass, ServiceName,
InstancePort, cInstanceNames, (LPCWSTR *)InstanceNames,
InstancePorts, &cSpns, &Spns);
Py_END_ALLOW_THREADS
if (err!=STATUS_SUCCESS)
PyWin_SetAPIError("DsGetSpn",err);
else{
ret=PyTuple_New(cSpns);
if (ret!=NULL){
for (tuple_index=0;tuple_index<cSpns;tuple_index++){
tuple_item=PyWinObject_FromWCHAR(Spns[tuple_index]);
if (tuple_item==NULL){
Py_DECREF(ret);
ret=NULL;
break;
}
PyTuple_SET_ITEM(ret, tuple_index, tuple_item);
}
}
}
done:
if (Spns!=NULL)
(*pfnDsFreeSpnArray)(cSpns, Spns);
PyWinObject_FreeWCHARArray(InstanceNames, cInstanceNames);
if (InstancePorts!=NULL)
free(InstancePorts);
if (obInstancePorts_tuple!=NULL)
Py_DECREF(obInstancePorts_tuple);
PyWinObject_FreeWCHAR(ServiceClass);
PyWinObject_FreeWCHAR(ServiceName);
return ret;
}
extern PyObject *PyDsWriteAccountSpn(PyObject *self, PyObject *args)
{
DWORD err, spn_cnt;
HANDLE dshandle;
DS_SPN_WRITE_OP Operation;
LPWSTR acct, *spns=NULL;
PyObject *ret=NULL, *obhandle, *obacct, *obspns;
CHECK_PFN(DsWriteAccountSpn);
if (!PyArg_ParseTuple(args, "OlOO:DsWriteAccountSpn", &obhandle, &Operation, &obacct, &obspns))
return NULL;
if (!PyWinObject_AsHANDLE(obhandle, &dshandle))
return NULL;
if (!PyWinObject_AsWCHAR(obacct, &acct))
goto done;
if (!PyWinObject_AsWCHARArray(obspns, &spns, &spn_cnt))
goto done;
Py_BEGIN_ALLOW_THREADS
err=(*pfnDsWriteAccountSpn)(dshandle, Operation, acct, spn_cnt, (LPCWSTR *)spns);
Py_END_ALLOW_THREADS
if (err!=STATUS_SUCCESS)
PyWin_SetAPIError("DsWriteAccountSpn", err);
else{
Py_INCREF(Py_None);
ret=Py_None;
}
done:
PyWinObject_FreeWCHAR(acct);
PyWinObject_FreeWCHARArray(spns, spn_cnt);
return ret;
}
PyObject *PyDsGetDcName(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kw_items[]= {
"computerName","domainName","domainGUID","siteName", "flags", NULL,
};
CHECK_PFN(DsGetDcName);
PyObject *obServer = Py_None, *obDomain = Py_None, *obSiteName = Py_None;
PyObject *obGUID = Py_None;
WCHAR *szServer = NULL, *szDomain = NULL, *szSiteName = NULL;
GUID guidBuf, *pGUID = NULL;
PyObject *ret = NULL;
DOMAIN_CONTROLLER_INFO *pdci = NULL;
DWORD flags = 0;
DWORD err;
if (!PyArg_ParseTupleAndKeywords(args, kw, "|OOOOi:DsGetDcName", kw_items,
&obServer,
&obDomain,
&obGUID,
&obSiteName,
&flags))
return NULL;
if (!PyWinObject_AsWCHAR(obServer, &szServer, TRUE))
goto done;
if (!PyWinObject_AsWCHAR(obDomain, &szDomain, TRUE))
goto done;
if (!PyWinObject_AsWCHAR(obSiteName, &szSiteName, TRUE))
goto done;
if (obGUID != Py_None) {
if (!PyWinObject_AsIID(obGUID, &guidBuf))
goto done;
pGUID = &guidBuf;
}
Py_BEGIN_ALLOW_THREADS
err = (*pfnDsGetDcName)(szServer, szDomain, pGUID, szSiteName, flags, &pdci);
Py_END_ALLOW_THREADS
if (err) {
PyWin_SetAPIError("DsGetDcName", err);
goto done;
}
ret = Py_BuildValue("{s:N,s:N,s:i,s:N,s:N,s:N,s:i,s:N,s:N}",
"DomainControllerName", PyWinObject_FromTCHAR(pdci->DomainControllerName),
"DomainControllerAddress", PyWinObject_FromTCHAR(pdci->DomainControllerAddress),
"DomainControllerAddressType", pdci->DomainControllerAddressType,
"DomainGuid", PyWinObject_FromIID(pdci->DomainGuid),
"DomainName", PyWinObject_FromTCHAR(pdci->DomainName),
"DnsForestName", PyWinObject_FromTCHAR(pdci->DnsForestName),
"Flags", pdci->Flags,
"DcSiteName", PyWinObject_FromTCHAR(pdci->DcSiteName),
"ClientSiteName", PyWinObject_FromTCHAR(pdci->ClientSiteName));
// @rdesc The result is a dictionary with keys having the same name as the
// Win32 DOMAIN_CONTROLLER_INFO struct.
done:
PyWinObject_FreeWCHAR(szServer);
PyWinObject_FreeWCHAR(szDomain);
PyWinObject_FreeWCHAR(szSiteName);
NetApiBufferFree(pdci);
return ret;
}
PyObject *PyDsCrackNames(PyObject *self, PyObject *args)
{
DWORD err;
HANDLE dshandle;
DS_NAME_FLAGS flags;
DS_NAME_FORMAT formatOffered, formatDesired;
PyObject *obNames;
PyObject *ret=NULL, *obhandle;
LPWSTR *names;
DWORD cnames;
PDS_NAME_RESULT dsresult = NULL;
CHECK_PFN(DsCrackNames);
CHECK_PFN(DsFreeNameResult);
if (!PyArg_ParseTuple(args, "OlllO:DsCrackNames", &obhandle, &flags, &formatOffered,
&formatDesired, &obNames))
return NULL;
if (!PyWinObject_AsHANDLE(obhandle, &dshandle, TRUE))
return NULL;
if (!PyWinObject_AsWCHARArray(obNames, &names, &cnames))
goto done;
Py_BEGIN_ALLOW_THREADS
err=(*pfnDsCrackNames)(dshandle, flags, formatOffered, formatDesired, cnames, names, &dsresult);
Py_END_ALLOW_THREADS
if (err!=STATUS_SUCCESS || !dsresult)
PyWin_SetAPIError("DsWriteAccountSpn", err);
else {
ret = PyList_New(dsresult->cItems);
if (!ret) goto done;
for (DWORD i=0;i<dsresult->cItems;i++) {
DS_NAME_RESULT_ITEM *pi = dsresult->rItems + i;
PyList_SET_ITEM(ret, i,
Py_BuildValue("iNN", pi->status,
PyWinObject_FromWCHAR(pi->pDomain),
PyWinObject_FromWCHAR(pi->pName)));
}
}
done:
PyWinObject_FreeWCHARArray(names, cnames);
if (dsresult)
(*pfnDsFreeNameResult)(dsresult);
return ret;
}
Index: win32security_sspi.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security_sspi.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** win32security_sspi.cpp 9 Mar 2005 10:23:42 -0000 1.3
--- win32security_sspi.cpp 24 May 2005 13:55:30 -0000 1.4
***************
*** 299,305 ****
--- 299,309 ----
#define OFF(e) offsetof(PySecBuffer, e)
struct PyMemberDef PySecBuffer::members[] = {
+ // @prop int|BufferType|
{"BufferType", T_ULONG, OFF(secbuffer.BufferType), 0, "Type of buffer, one of the SECBUFFER_* constants - can also be combined with SECBUFFER_READONLY"},
+ // @prop string|Buffer|
{"Buffer", T_OBJECT, OFF(obdummy), 0, "Encoded data buffer"},
+ // @prop int|BufferSize|
{"BufferSize", T_ULONG, OFF(secbuffer.cbBuffer), 0, "Current size of data in buffer"},
+ // @prop int|MaxBufferSize|
{"MaxBufferSize", T_ULONG, OFF(maxbufsize), READONLY, "Maximum size of data buffer"},
{NULL}
***************
*** 626,630 ****
--- 630,636 ----
return NULL;
PCtxtHandle pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->MakeSignature)(pctxt, fqop, psecbufferdesc, seq_no);
+ Py_END_ALLOW_THREADS
if (err<0){
PyWin_SetAPIError("MakeSignature",err);
***************
*** 686,690 ****
--- 692,698 ----
return NULL;
PCtxtHandle pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->EncryptMessage)(pctxt, fqop, psecbufferdesc, seq_no);
+ Py_END_ALLOW_THREADS
if (err<0){
PyWin_SetAPIError("EncryptMessage",err);
***************
*** 718,722 ****
--- 726,732 ----
return NULL;
PCtxtHandle pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->DecryptMessage)(pctxt, psecbufferdesc, seq_no, &fqop);
+ Py_END_ALLOW_THREADS
((PySecBufferDesc *)obdesc)->modify_in_place();
if (err==SEC_E_OK)
***************
*** 774,778 ****
--- 784,790 ----
return NULL;
pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->CompleteAuthToken)(pctxt, psecbufferdesc);
+ Py_END_ALLOW_THREADS
if (err==SEC_E_OK){
Py_INCREF(Py_None);
***************
*** 798,802 ****
--- 810,816 ----
pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->QueryContextAttributesW)(pctxt, attr, &buf);
+ Py_END_ALLOW_THREADS
if (err!=SEC_E_OK){
PyWin_SetAPIError("QueryContextAttributes",err);
***************
*** 965,969 ****
--- 979,985 ----
return NULL;
pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->QuerySecurityContextToken)(pctxt, &htoken);
+ Py_END_ALLOW_THREADS
if (err==SEC_E_OK)
return PyWinObject_FromHANDLE(htoken);
***************
*** 981,985 ****
--- 997,1003 ----
return NULL;
pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->ImpersonateSecurityContext)(pctxt);
+ Py_END_ALLOW_THREADS
if (err==SEC_E_OK){
Py_INCREF(Py_None);
***************
*** 999,1003 ****
--- 1017,1023 ----
return NULL;
pctxt=((PyCtxtHandle *)self)->GetCtxtHandle();
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->RevertSecurityContext)(pctxt);
+ Py_END_ALLOW_THREADS
if (err==SEC_E_OK){
Py_INCREF(Py_None);
***************
*** 1190,1194 ****
--- 1210,1216 ----
if (!PyArg_ParseTuple(args, "l:QueryCredentialsAttributes", &attr))
return NULL;
+ Py_BEGIN_ALLOW_THREADS
err=(*psecurityfunctiontable->QueryCredentialsAttributesW)(pcredhandle, attr, &buf);
+ Py_END_ALLOW_THREADS
if (err!=SEC_E_OK){
PyWin_SetAPIError("QueryCredentialsAttributes",err);
***************
*** 1216,1458 ****
}
- // Directory service handle, yet another type of PyHANDLE
- // @object PyDS_HANDLE|Directory service handle, returned by <om win32security.DsBind>
- // Subtype of <o PyHANDLE>, inherits all properties and methods
- class PyDS_HANDLE: public PyHANDLE
- {
- public:
- PyDS_HANDLE(HANDLE hInit) : PyHANDLE(hInit) {}
- virtual BOOL Close(void) {
- DWORD err;
- if (!m_handle)
- return TRUE; // already closed or Detached, nothing to do
- if (pfnDsUnBind==NULL){
- // should not happen if functions to create a Ds handle exist ...
- PyErr_SetString(PyExc_SystemError,"Error closing PyDS_HANDLE, DsUnBind is NULL");
- return FALSE;
- }
- err = (*pfnDsUnBind)(&m_handle);
- // ??? This function apparently never returns an error, no matter what you pass to it ???
- if (err==NO_ERROR){
- m_handle = 0;
- return TRUE;
- }
- PyWin_SetAPIError("PyDS_HANDLE::Close", err);
- return FALSE;
- }
- virtual const char *GetTypeName(){
- return "PyDS_HANDLE";
- }
- };
-
- // directory service functions for registering target Spns to be used with Kerberos
- extern PyObject *PyDsBind(PyObject *self, PyObject *args)
- {
- WCHAR *dc=NULL, *domain=NULL;
- PyObject *obdc=Py_None, *obdomain=Py_None;
- PyObject *ret=NULL;
- DWORD err;
- HANDLE dshandle;
-
- CHECK_PFN(DsBind);
- if (!PyArg_ParseTuple(args, "|OO:DsBind", obdc, obdomain))
- return NULL;
- if (PyWinObject_AsWCHAR(obdc, &dc, TRUE) &&
- PyWinObject_AsWCHAR(obdomain, &domain, TRUE)){
- err=(*pfnDsBind)(dc, domain, &dshandle);
- if (err==NO_ERROR)
- ret=new PyDS_HANDLE(dshandle);
- else
- PyWin_SetAPIError("DsBind",err);
- }
- PyWinObject_FreeWCHAR(dc);
- PyWinObject_FreeWCHAR(domain);
- return ret;
- }
-
- extern PyObject *PyDsUnBind(PyObject *self, PyObject *args)
- {
- DWORD err;
- HANDLE dshandle;
- PyObject *obhandle;
-
- CHECK_PFN(DsUnBind);
- if (!PyArg_ParseTuple(args, "O:DsUnBind", &obhandle))
- return NULL;
- if (!PyWinObject_AsHANDLE(obhandle, &dshandle))
- return NULL;
- err=(*pfnDsUnBind)(&dshandle);
- if (err==NO_ERROR){
- Py_INCREF(Py_None);
- return Py_None;
- }
- PyWin_SetAPIError("DsUnBind",err);
- return NULL;
- }
-
- void PyWinObject_FreeWCHARArray(LPWSTR *wchars, DWORD str_cnt)
- {
- if (wchars!=NULL){
- for (DWORD wchar_index=0; wchar_index<str_cnt; wchar_index++)
- PyWinObject_FreeWCHAR(wchars[wchar_index]);
- free(wchars);
- }
- }
-
- BOOL PyWinObject_AsWCHARArray(PyObject *str_seq, LPWSTR **wchars, DWORD *str_cnt)
- {
- BOOL ret=FALSE;
- PyObject *str_tuple=NULL, *tuple_item;
- DWORD bufsize, tuple_index;
- *wchars=NULL;
- *str_cnt=0;
- if ((str_tuple=PySequence_Tuple(str_seq))==NULL)
- return FALSE;
- *str_cnt=PyTuple_Size(str_tuple);
- bufsize=*str_cnt * sizeof(LPWSTR);
- *wchars=(LPWSTR *)malloc(bufsize);
- if (*wchars==NULL){
- PyErr_Format(PyExc_MemoryError, "Unable to allocate %d bytes", bufsize);
- goto done;
- }
- ZeroMemory(*wchars, bufsize);
- for (tuple_index=0;tuple_index<*str_cnt;tuple_index++){
- tuple_item=PyTuple_GET_ITEM(str_tuple, tuple_index);
- if (!PyWinObject_AsWCHAR(tuple_item, &((*wchars)[tuple_index]), FALSE)){
- PyWinObject_FreeWCHARArray(*wchars, *str_cnt);
- *wchars=NULL;
- *str_cnt=0;
- goto done;
- }
- }
- ret=TRUE;
- done:
- Py_XDECREF(str_tuple);
- return ret;
- }
-
- extern PyObject *PyDsGetSpn(PyObject *self, PyObject *args)
- {
- DWORD err, cSpns, bufsize, name_cnt;
- DS_SPN_NAME_TYPE ServiceType;
- WCHAR *ServiceClass=NULL, *ServiceName=NULL;
- PyObject *obServiceClass, *obServiceName;
- PyObject *ret=NULL, *tuple_item;
- LPWSTR *Spns=NULL, *InstanceNames=NULL;
- USHORT tuple_index, InstancePort=0, cInstanceNames=0, *InstancePorts=NULL;
- long port_nbr;
- PyObject *obInstanceNames=Py_None, *obInstancePorts=Py_None;
- PyObject *obInstancePorts_tuple=NULL;
-
- CHECK_PFN(DsGetSpn);
- CHECK_PFN(DsFreeSpnArray);
-
- if (!PyArg_ParseTuple(args,"lOO|HOO:DsGetSpn", &ServiceType, &obServiceClass, &obServiceName,
- &InstancePort, &obInstanceNames, &obInstancePorts))
- return NULL;
- if (!PyWinObject_AsWCHAR(obServiceClass, &ServiceClass, FALSE))
- goto done;
- if (!PyWinObject_AsWCHAR(obServiceName, &ServiceName, TRUE))
- goto done;
- if (obInstanceNames!=Py_None){
- if (!PyWinObject_AsWCHARArray(obInstanceNames, &InstanceNames, &name_cnt))
- goto done;
- if (name_cnt>USHRT_MAX){
- PyErr_Format(PyExc_ValueError, "Count of InstanceNames cannot exceed %d", USHRT_MAX);
- goto done;
- }
- cInstanceNames=(USHORT)name_cnt;
- }
-
- if (obInstancePorts!=Py_None){
- if ((obInstancePorts_tuple=PySequence_Tuple(obInstancePorts))==NULL)
- goto done;
- if (PyTuple_Size(obInstancePorts_tuple)!=cInstanceNames){
- PyErr_SetString(PyExc_ValueError,"DsGetSpn: InstancePorts must be same size sequence as InstanceNames");
- goto done;
- }
- bufsize=cInstanceNames * sizeof(USHORT);
- InstancePorts=(USHORT *)malloc(bufsize);
- if (InstancePorts==NULL){
- PyErr_Format(PyExc_MemoryError, "DsGetSpn: Unable to allocate %d bytes", bufsize);
- goto done;
- }
- for (tuple_index=0;tuple_index<cInstanceNames;tuple_index++){
- tuple_item=PyTuple_GET_ITEM(obInstancePorts_tuple,tuple_index);
- // convert a python int to a USHORT
- // ??? any API function to do this other than H format of PyArg_ParseTuple ???
- port_nbr=PyInt_AsLong(tuple_item);
- if ((port_nbr==(unsigned long)-1 && PyErr_Occurred()) || (port_nbr<0)){
- PyErr_Clear();
- PyErr_Format(PyExc_TypeError,"InstancePorts must be a sequence of ints in the range 0-%d",USHRT_MAX);
- goto done;
- }
- if (port_nbr > USHRT_MAX){
- PyErr_Format(PyExc_ValueError, "InstancePorts values cannot exceed %d", USHRT_MAX);
- goto done;
- }
- InstancePorts[tuple_index]=(USHORT)port_nbr;
- }
- }
-
- err=(*pfnDsGetSpn)(ServiceType, ServiceClass, ServiceName,
- InstancePort, cInstanceNames, (LPCWSTR *)InstanceNames,
- InstancePorts, &cSpns, &Spns);
- if (err!=STATUS_SUCCESS)
- PyWin_SetAPIError("DsGetSpn",err);
- else{
- ret=PyTuple_New(cSpns);
- if (ret!=NULL){
- for (tuple_index=0;tuple_index<cSpns;tuple_index++){
- tuple_item=PyWinObject_FromWCHAR(Spns[tuple_index]);
- if (tuple_item==NULL){
- Py_DECREF(ret);
- ret=NULL;
- break;
- }
- PyTuple_SET_ITEM(ret, tuple_index, tuple_item);
- }
- }
- }
- done:
- if (Spns!=NULL)
- (*pfnDsFreeSpnArray)(cSpns, Spns);
- PyWinObject_FreeWCHARArray(InstanceNames, cInstanceNames);
-
- if (InstancePorts!=NULL)
- free(InstancePorts);
- if (obInstancePorts_tuple!=NULL)
- Py_DECREF(obInstancePorts_tuple);
- PyWinObject_FreeWCHAR(ServiceClass);
- PyWinObject_FreeWCHAR(ServiceName);
- return ret;
- }
-
- extern PyObject *PyDsWriteAccountSpn(PyObject *self, PyObject *args)
- {
- DWORD err, spn_cnt;
- HANDLE dshandle;
- DS_SPN_WRITE_OP Operation;
- LPWSTR acct, *spns=NULL;
- PyObject *ret=NULL, *obhandle, *obacct, *obspns;
- CHECK_PFN(DsWriteAccountSpn);
- if (!PyArg_ParseTuple(args, "OlOO:DsWriteAccountSpn", &obhandle, &Operation, &obacct, &obspns))
- return NULL;
- if (!PyWinObject_AsHANDLE(obhandle, &dshandle))
- return NULL;
- if (!PyWinObject_AsWCHAR(obacct, &acct))
- goto done;
- if (!PyWinObject_AsWCHARArray(obspns, &spns, &spn_cnt))
- goto done;
- err=(*pfnDsWriteAccountSpn)(dshandle, Operation, acct, spn_cnt, (LPCWSTR *)spns);
- if (err!=STATUS_SUCCESS)
- PyWin_SetAPIError("DsWriteAccountSpn", err);
- else{
- Py_INCREF(Py_None);
- ret=Py_None;
- }
- done:
- PyWinObject_FreeWCHAR(acct);
- PyWinObject_FreeWCHARArray(spns, spn_cnt);
- return ret;
- }
--- 1238,1239 ----
Index: win32security_sspi.h
===================================================================
RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security_sspi.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** win32security_sspi.h 8 Mar 2005 13:13:03 -0000 1.2
--- win32security_sspi.h 24 May 2005 13:55:30 -0000 1.3
***************
*** 6,9 ****
--- 6,10 ----
#include "ntdsapi.h"
#include "subauth.h"
+ #include "Dsgetdc.h"
// SecBuffer objects for SSPI functionality
***************
*** 160,163 ****
--- 161,165 ----
PyObject *PyDsBind(PyObject *self, PyObject *args);
PyObject *PyDsUnBind(PyObject *self, PyObject *args);
+ PyObject *PyDsGetDcName(PyObject *self, PyObject *args, PyObject *kw);
// function pointers that are initialized in win32security.i and used in win32security_sspi.cpp
***************
*** 178,181 ****
--- 180,192 ----
extern DsWriteAccountSpnfunc pfnDsWriteAccountSpn;
+ typedef DWORD (WINAPI *DsGetDcNamefunc)(LPCTSTR, LPCTSTR, GUID *, LPCTSTR, ULONG, PDOMAIN_CONTROLLER_INFO *);
+ extern DsGetDcNamefunc pfnDsGetDcName;
+
+ typedef DWORD (WINAPI *DsCrackNamesfunc)(HANDLE, DS_NAME_FLAGS, DS_NAME_FORMAT, DS_NAME_FORMAT, DWORD, LPTSTR *, PDS_NAME_RESULT *);
+ extern DsCrackNamesfunc pfnDsCrackNames;
+
+ typedef VOID (WINAPI *DsFreeNameResultfunc)(DS_NAME_RESULTW *);
+ extern DsFreeNameResultfunc pfnDsFreeNameResult;
+
#define CHECK_PFN(fname) if (pfn##fname==NULL) return PyErr_Format(PyExc_NotImplementedError,"%s is not available on this platform", #fname);
Index: win32security.i
===================================================================
RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security.i,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -d -r1.24 -r1.25
*** win32security.i 16 Apr 2005 01:29:35 -0000 1.24
--- win32security.i 24 May 2005 13:55:29 -0000 1.25
***************
*** 77,80 ****
--- 77,83 ----
extern PSecurityFunctionTableW psecurityfunctiontable=NULL;
+ typedef BOOL (WINAPI *TranslateNamefunc)(LPCTSTR, EXTENDED_NAME_FORMAT, EXTENDED_NAME_FORMAT, LPTSTR, PULONG);
+ static TranslateNamefunc pfnTranslateName=NULL;
+
// function pointers used in win32security_sspi.cpp
extern DsBindfunc pfnDsBind=NULL;
***************
*** 83,86 ****
--- 86,92 ----
extern DsWriteAccountSpnfunc pfnDsWriteAccountSpn=NULL;
extern DsFreeSpnArrayfunc pfnDsFreeSpnArray=NULL;
+ extern DsGetDcNamefunc pfnDsGetDcName=NULL;
+ extern DsCrackNamesfunc pfnDsCrackNames=NULL;
+ extern DsFreeNameResultfunc pfnDsFreeNameResult=NULL;
static HMODULE advapi32_dll=NULL;
***************
*** 89,92 ****
--- 95,99 ----
static HMODULE ntdll_dll =NULL;
static HMODULE ntdsapi_dll =NULL;
+ static HMODULE netapi32_dll=NULL;
HMODULE loadmodule(WCHAR *dllname)
***************
*** 595,598 ****
--- 602,606 ----
ntdll_dll =loadmodule(_T("ntdll.dll"));
ntdsapi_dll =loadmodule(_T("ntdsapi.dll"));
+ netapi32_dll =loadmodule(_T("netapi32.dll"));
pfnCheckTokenMembership=(CheckTokenMembershipfunc)loadapifunc("CheckTokenMembership", advapi32_dll);
***************
*** 634,637 ****
--- 642,647 ----
if (pfnInitSecurityInterface!=NULL)
psecurityfunctiontable=(*pfnInitSecurityInterface)();
+
+ pfnTranslateName=(TranslateNamefunc)loadapifunc("TranslateNameW",secur32_dll);
pfnDsBind=(DsBindfunc)loadapifunc("DsBindW", ntdsapi_dll);
***************
*** 640,643 ****
--- 650,656 ----
pfnDsWriteAccountSpn=(DsWriteAccountSpnfunc)loadapifunc("DsWriteAccountSpnW", ntdsapi_dll);
pfnDsFreeSpnArray=(DsFreeSpnArrayfunc)loadapifunc("DsFreeSpnArrayW", ntdsapi_dll);
+ pfnDsCrackNames=(DsCrackNamesfunc)loadapifunc("DsCrackNamesW", ntdsapi_dll);
+ pfnDsFreeNameResult=(DsFreeNameResultfunc)loadapifunc("DsFreeNameResultW", ntdsapi_dll);
+ pfnDsGetDcName=(DsGetDcNamefunc)loadapifunc("DsGetDcNameW", netapi32_dll);
PyDict_SetItemString(d, "SecBufferType", (PyObject *)&PySecBufferType);
***************
*** 645,648 ****
--- 658,668 ----
PyDict_SetItemString(d, "CtxtHandleType", (PyObject *)&PyCtxtHandleType);
PyDict_SetItemString(d, "CredHandleType", (PyObject *)&PyCredHandleType);
+
+ // Patch up any kwarg functions - SWIG doesn't like them.
+ for (PyMethodDef *pmd = win32securityMethods;pmd->ml_name;pmd++)
+ if (strcmp(pmd->ml_name, "DsGetDcName")==0) {
+ pmd->ml_flags = METH_VARARGS | METH_KEYWORDS;
+ break; // only 1 name at the moment.
+ }
%}
***************
*** 673,676 ****
--- 693,717 ----
// @pyparm <o PyHANDLE>|hDS||A handle to a directory service as returned by <om win32security.DsBind>
+ %{
+ // work around issues with SWIG and kwargs.
+ #define PYDSGETDCNAME (PyCFunction)PyDsGetDcName
+ %}
+ %native (DsGetDcName) PYDSGETDCNAME;
+ // @pyswig dict|DsGetDcName|Returns the name of a domain controller (DC) in a specified domain.
+ // You can supply DC selection criteria to this function to indicate preference for a DC with particular characteristics.
+ // @comm This function supports keyword arguments.
+ // @pyparm <o PyUnicode>|computerName|None|
+ // @pyparm <o PyUnicode>|domainName|None|
+ // @pyparm <o PyIID>|domainGUID|None|
+ // @pyparm <o PyUnicode>|siteName|None|
+ // @pyparm int|flags|0|
+
+ %native (DsCrackNames) extern PyObject *PyDsCrackNames(PyObject *self, PyObject *args);
+ // @pyswig [ (status, domain, name) ]|DsCrackNames|Converts an array of directory service object names from one format to another.
+ // @pyswig int|flags||
+ // @pyparm int|formatOffered||
+ // @pyparm int|formatDesired||
+ // @pyparm [name, ...]|names||
+
// @pyswig PyACL|ACL|Creates a new <o PyACL> object.
// @pyparm int|bufSize|64|The size of the buffer for the ACL.
***************
*** 3353,3356 ****
--- 3394,3437 ----
%}
+ // @pyswig |TranslateName|Converts a directory service object name from one format to another.
+ %native(TranslateName) PyTranslateName;
+ %{
+ static PyObject *PyTranslateName(PyObject *self, PyObject *args)
+ {
+ PyObject *obAcctName;
+ int format, desiredFormat;
+ ULONG numChars = 1024;
+ CHECK_PFN(TranslateName);
+ WCHAR *szAcctName = NULL;
+ WCHAR *buf = NULL;
+ BOOL ok;
+ if (!PyArg_ParseTuple(args, "Oii|l",
+ &obAcctName, // @pyparm <o PyUnicode>|accountName||object name
+ &format, // @pyparm int|accountNameFormat||A value from the EXTENDED_NAME_FORMAT enumeration type indicating the format of the accountName name.
+ &desiredFormat, // @pyparm int|accountNameFormat||A value from the EXTENDED_NAME_FORMAT enumeration type indicating the format of the desired name.
+ &numChars)) // @pyparm int|numChars|1024|Number of Unicode characters to allocate for the return buffer.
+ return NULL;
+ if (!PyWinObject_AsWCHAR(obAcctName, &szAcctName, FALSE))
+ return NULL;
+ buf = (WCHAR *)malloc(sizeof(WCHAR) * numChars);
+ if (!buf) {
+ PyWinObject_FreeWCHAR(szAcctName);
+ return PyErr_NoMemory();
+ }
+ Py_BEGIN_ALLOW_THREADS
+ ok = (*pfnTranslateName)(szAcctName, (EXTENDED_NAME_FORMAT)format,
+ (EXTENDED_NAME_FORMAT)desiredFormat, buf, &numChars);
+ Py_END_ALLOW_THREADS
+ PyObject *ret = NULL;
+ if (ok) {
+ ret = PyWinObject_FromWCHAR(buf, numChars-1);
+ } else
+ PyWin_SetAPIError("TranslateName");
+ PyWinObject_FreeWCHAR(szAcctName);
+ free(buf);
+ return ret;
+ }
+ %}
+
#define TOKEN_ADJUST_DEFAULT TOKEN_ADJUST_DEFAULT // Required to change the default ACL, primary group, or owner of an access token.
#define TOKEN_ADJUST_GROUPS TOKEN_ADJUST_GROUPS // Required to change the groups specified in an access token.
|