Changeset 745 for trunk/server/source4/libnet/py_net.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/libnet/py_net.c
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 Samba utility functions 4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 5 4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010 5 Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009 6 6 7 This program is free software; you can redistribute it and/or modify 7 8 it under the terms of the GNU General Public License as published by 8 9 the Free Software Foundation; either version 3 of the License, or 9 10 (at your option) any later version. 10 11 11 12 This program is distributed in the hope that it will be useful, 12 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 15 GNU General Public License for more details. 15 16 16 17 You should have received a copy of the GNU General Public License 17 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19 */ 19 20 21 #include <Python.h> 20 22 #include "includes.h" 21 #include <Python.h> 23 #include <ldb.h> 24 #include <pyldb.h> 22 25 #include "libnet.h" 23 26 #include "auth/credentials/pycredentials.h" 24 27 #include "libcli/security/security.h" 25 28 #include "lib/events/events.h" 26 #include "param/param.h" 27 28 /* FIXME: This prototype should be in param/pyparam.h */ 29 struct loadparm_context *py_default_loadparm_context(TALLOC_CTX *mem_ctx); 30 31 static struct libnet_context *py_net_ctx(PyObject *obj, struct tevent_context *ev, struct cli_credentials *creds) 32 { 33 /* FIXME: Use obj */ 34 struct libnet_context *libnet; 35 libnet = libnet_context_init(ev, py_default_loadparm_context(NULL)); 36 if (!libnet) { 37 return NULL; 38 } 39 libnet->cred = creds; 40 return libnet; 41 } 42 43 static PyObject *py_net_join(PyObject *cls, PyObject *args, PyObject *kwargs) 29 #include "param/pyparam.h" 30 #include "auth/gensec/gensec.h" 31 #include "librpc/rpc/pyrpc_util.h" 32 #include "libcli/finddc.h" 33 #include "libcli/resolve/resolve.h" 34 35 void initnet(void); 36 37 typedef struct { 38 PyObject_HEAD 39 TALLOC_CTX *mem_ctx; 40 struct libnet_context *libnet_ctx; 41 struct tevent_context *ev; 42 } py_net_Object; 43 44 static PyObject *py_net_join(py_net_Object *self, PyObject *args, PyObject *kwargs) 44 45 { 45 46 struct libnet_Join r; … … 47 48 PyObject *result; 48 49 TALLOC_CTX *mem_ctx; 50 const char *kwnames[] = { "domain_name", "netbios_name", "join_type", "level", NULL }; 51 52 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssii:Join", discard_const_p(char *, kwnames), 53 &r.in.domain_name, &r.in.netbios_name, 54 &r.in.join_type, &r.in.level)) 55 return NULL; 56 57 mem_ctx = talloc_new(self->mem_ctx); 58 if (mem_ctx == NULL) { 59 PyErr_NoMemory(); 60 return NULL; 61 } 62 63 status = libnet_Join(self->libnet_ctx, mem_ctx, &r); 64 if (NT_STATUS_IS_ERR(status)) { 65 PyErr_SetString(PyExc_RuntimeError, r.out.error_string?r.out.error_string:nt_errstr(status)); 66 talloc_free(mem_ctx); 67 return NULL; 68 } 69 70 result = Py_BuildValue("sss", r.out.join_password, 71 dom_sid_string(mem_ctx, r.out.domain_sid), 72 r.out.domain_name); 73 74 talloc_free(mem_ctx); 75 76 return result; 77 } 78 79 static const char py_net_join_doc[] = "join(domain_name, netbios_name, join_type, level) -> (join_password, domain_sid, domain_name)\n\n" \ 80 "Join the domain with the specified name."; 81 82 static PyObject *py_net_set_password(py_net_Object *self, PyObject *args, PyObject *kwargs) 83 { 84 union libnet_SetPassword r; 85 NTSTATUS status; 86 PyObject *py_creds; 87 TALLOC_CTX *mem_ctx; 49 88 struct tevent_context *ev; 50 struct libnet_context *libnet_ctx;51 struct cli_credentials *creds; 52 PyObject *py_creds;53 const char *kwnames[] = { "domain_name", "netbios_name", "join_type", "level", "credentials", NULL }; 54 55 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssiiO:Join", discard_const_p(char *, kwnames),56 &r. in.domain_name, &r.in.netbios_name,57 &r.in.join_type, &r.in.level, &py_creds))58 return NULL;89 const char *kwnames[] = { "account_name", "domain_name", "newpassword", "credentials", NULL }; 90 91 r.generic.level = LIBNET_SET_PASSWORD_GENERIC; 92 93 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sssO:set_password", discard_const_p(char *, kwnames), 94 &r.generic.in.account_name, &r.generic.in.domain_name, 95 &r.generic.in.newpassword, &py_creds)) { 96 return NULL; 97 } 59 98 60 99 /* FIXME: we really need to get a context from the caller or we may end 61 100 * up with 2 event contexts */ 62 101 ev = s4_event_context_init(NULL); 102 63 103 mem_ctx = talloc_new(ev); 64 65 creds = cli_credentials_from_py_object(py_creds); 66 if (creds == NULL) { 104 if (mem_ctx == NULL) { 105 PyErr_NoMemory(); 106 return NULL; 107 } 108 109 status = libnet_SetPassword(self->libnet_ctx, mem_ctx, &r); 110 if (NT_STATUS_IS_ERR(status)) { 111 PyErr_SetString(PyExc_RuntimeError, 112 r.generic.out.error_string?r.generic.out.error_string:nt_errstr(status)); 113 talloc_free(mem_ctx); 114 return NULL; 115 } 116 117 talloc_free(mem_ctx); 118 119 Py_RETURN_NONE; 120 } 121 122 static const char py_net_set_password_doc[] = "set_password(account_name, domain_name, newpassword) -> True\n\n" \ 123 "Set password for a user. You must supply credential with enough rights to do this.\n\n" \ 124 "Sample usage is:\n" \ 125 "net.set_password(account_name=<account_name>,\n" \ 126 " domain_name=domain_name,\n" \ 127 " newpassword=new_pass)\n"; 128 129 130 static PyObject *py_net_export_keytab(py_net_Object *self, PyObject *args, PyObject *kwargs) 131 { 132 struct libnet_export_keytab r; 133 TALLOC_CTX *mem_ctx; 134 const char *kwnames[] = { "keytab", NULL }; 135 NTSTATUS status; 136 137 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:export_keytab", discard_const_p(char *, kwnames), 138 &r.in.keytab_name)) { 139 return NULL; 140 } 141 142 mem_ctx = talloc_new(self->mem_ctx); 143 if (mem_ctx == NULL) { 144 PyErr_NoMemory(); 145 return NULL; 146 } 147 148 status = libnet_export_keytab(self->libnet_ctx, mem_ctx, &r); 149 if (NT_STATUS_IS_ERR(status)) { 150 PyErr_SetString(PyExc_RuntimeError, 151 r.out.error_string?r.out.error_string:nt_errstr(status)); 152 talloc_free(mem_ctx); 153 return NULL; 154 } 155 156 talloc_free(mem_ctx); 157 158 Py_RETURN_NONE; 159 } 160 161 static const char py_net_export_keytab_doc[] = "export_keytab(keytab, name)\n\n" 162 "Export the DC keytab to a keytab file."; 163 164 static PyObject *py_net_time(py_net_Object *self, PyObject *args, PyObject *kwargs) 165 { 166 const char *kwnames[] = { "server_name", NULL }; 167 union libnet_RemoteTOD r; 168 NTSTATUS status; 169 TALLOC_CTX *mem_ctx; 170 char timestr[64]; 171 PyObject *ret; 172 struct tm *tm; 173 174 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", 175 discard_const_p(char *, kwnames), &r.generic.in.server_name)) 176 return NULL; 177 178 r.generic.level = LIBNET_REMOTE_TOD_GENERIC; 179 180 mem_ctx = talloc_new(NULL); 181 if (mem_ctx == NULL) { 182 PyErr_NoMemory(); 183 return NULL; 184 } 185 186 status = libnet_RemoteTOD(self->libnet_ctx, mem_ctx, &r); 187 if (!NT_STATUS_IS_OK(status)) { 188 PyErr_SetString(PyExc_RuntimeError, 189 r.generic.out.error_string?r.generic.out.error_string:nt_errstr(status)); 190 talloc_free(mem_ctx); 191 return NULL; 192 } 193 194 ZERO_STRUCT(timestr); 195 tm = localtime(&r.generic.out.time); 196 strftime(timestr, sizeof(timestr)-1, "%c %Z",tm); 197 198 ret = PyString_FromString(timestr); 199 200 talloc_free(mem_ctx); 201 202 return ret; 203 } 204 205 static const char py_net_time_doc[] = "time(server_name) -> timestr\n" 206 "Retrieve the remote time on a server"; 207 208 static PyObject *py_net_user_create(py_net_Object *self, PyObject *args, PyObject *kwargs) 209 { 210 const char *kwnames[] = { "username", NULL }; 211 NTSTATUS status; 212 TALLOC_CTX *mem_ctx; 213 struct libnet_CreateUser r; 214 215 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", discard_const_p(char *, kwnames), 216 &r.in.user_name)) 217 return NULL; 218 219 r.in.domain_name = cli_credentials_get_domain(self->libnet_ctx->cred); 220 221 mem_ctx = talloc_new(NULL); 222 if (mem_ctx == NULL) { 223 PyErr_NoMemory(); 224 return NULL; 225 } 226 227 status = libnet_CreateUser(self->libnet_ctx, mem_ctx, &r); 228 if (!NT_STATUS_IS_OK(status)) { 229 PyErr_SetString(PyExc_RuntimeError, r.out.error_string?r.out.error_string:nt_errstr(status)); 230 talloc_free(mem_ctx); 231 return NULL; 232 } 233 234 talloc_free(mem_ctx); 235 236 Py_RETURN_NONE; 237 } 238 239 static const char py_net_create_user_doc[] = "create_user(username)\n" 240 "Create a new user."; 241 242 static PyObject *py_net_user_delete(py_net_Object *self, PyObject *args, PyObject *kwargs) 243 { 244 const char *kwnames[] = { "username", NULL }; 245 NTSTATUS status; 246 TALLOC_CTX *mem_ctx; 247 struct libnet_DeleteUser r; 248 249 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", discard_const_p(char *, kwnames), 250 &r.in.user_name)) 251 return NULL; 252 253 r.in.domain_name = cli_credentials_get_domain(self->libnet_ctx->cred); 254 255 mem_ctx = talloc_new(NULL); 256 if (mem_ctx == NULL) { 257 PyErr_NoMemory(); 258 return NULL; 259 } 260 261 status = libnet_DeleteUser(self->libnet_ctx, mem_ctx, &r); 262 if (!NT_STATUS_IS_OK(status)) { 263 PyErr_SetString(PyExc_RuntimeError, r.out.error_string?r.out.error_string:nt_errstr(status)); 264 talloc_free(mem_ctx); 265 return NULL; 266 } 267 268 talloc_free(mem_ctx); 269 270 Py_RETURN_NONE; 271 } 272 273 static const char py_net_delete_user_doc[] = "delete_user(username)\n" 274 "Delete a user."; 275 276 static PyObject *py_dom_sid_FromSid(struct dom_sid *sid) 277 { 278 PyObject *mod_security, *dom_sid_Type; 279 280 mod_security = PyImport_ImportModule("samba.dcerpc.security"); 281 if (mod_security == NULL) 282 return NULL; 283 284 dom_sid_Type = PyObject_GetAttrString(mod_security, "dom_sid"); 285 if (dom_sid_Type == NULL) 286 return NULL; 287 288 return py_talloc_reference((PyTypeObject *)dom_sid_Type, sid); 289 } 290 291 static PyObject *py_net_vampire(py_net_Object *self, PyObject *args, PyObject *kwargs) 292 { 293 const char *kwnames[] = { "domain", "target_dir", NULL }; 294 NTSTATUS status; 295 TALLOC_CTX *mem_ctx; 296 PyObject *ret; 297 struct libnet_Vampire r; 298 299 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|z", discard_const_p(char *, kwnames), 300 &r.in.domain_name, &r.in.targetdir)) { 301 return NULL; 302 } 303 304 r.in.netbios_name = lpcfg_netbios_name(self->libnet_ctx->lp_ctx); 305 r.out.error_string = NULL; 306 307 mem_ctx = talloc_new(NULL); 308 if (mem_ctx == NULL) { 309 PyErr_NoMemory(); 310 return NULL; 311 } 312 313 status = libnet_Vampire(self->libnet_ctx, mem_ctx, &r); 314 315 if (!NT_STATUS_IS_OK(status)) { 316 PyErr_SetString(PyExc_RuntimeError, 317 r.out.error_string ? r.out.error_string : nt_errstr(status)); 318 talloc_free(mem_ctx); 319 return NULL; 320 } 321 322 ret = Py_BuildValue("(sO)", r.out.domain_name, py_dom_sid_FromSid(r.out.domain_sid)); 323 324 talloc_free(mem_ctx); 325 326 return ret; 327 } 328 329 struct replicate_state { 330 void *vampire_state; 331 dcerpc_InterfaceObject *drs_pipe; 332 struct libnet_BecomeDC_StoreChunk chunk; 333 DATA_BLOB gensec_skey; 334 struct libnet_BecomeDC_Partition partition; 335 struct libnet_BecomeDC_Forest forest; 336 struct libnet_BecomeDC_DestDSA dest_dsa; 337 }; 338 339 /* 340 setup for replicate_chunk() calls 341 */ 342 static PyObject *py_net_replicate_init(py_net_Object *self, PyObject *args, PyObject *kwargs) 343 { 344 const char *kwnames[] = { "samdb", "lp", "drspipe", NULL }; 345 PyObject *py_ldb, *py_lp, *py_drspipe; 346 struct ldb_context *samdb; 347 struct loadparm_context *lp; 348 struct replicate_state *s; 349 NTSTATUS status; 350 351 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO", 352 discard_const_p(char *, kwnames), 353 &py_ldb, &py_lp, &py_drspipe)) { 354 return NULL; 355 } 356 357 s = talloc_zero(NULL, struct replicate_state); 358 if (!s) return NULL; 359 360 lp = lpcfg_from_py_object(s, py_lp); 361 if (lp == NULL) { 362 PyErr_SetString(PyExc_TypeError, "Expected lp object"); 363 talloc_free(s); 364 return NULL; 365 } 366 367 samdb = PyLdb_AsLdbContext(py_ldb); 368 if (samdb == NULL) { 369 PyErr_SetString(PyExc_TypeError, "Expected ldb object"); 370 talloc_free(s); 371 return NULL; 372 } 373 374 s->drs_pipe = (dcerpc_InterfaceObject *)(py_drspipe); 375 376 s->vampire_state = libnet_vampire_replicate_init(s, samdb, lp); 377 if (s->vampire_state == NULL) { 378 PyErr_SetString(PyExc_TypeError, "Failed to initialise vampire_state"); 379 talloc_free(s); 380 return NULL; 381 } 382 383 status = gensec_session_key(s->drs_pipe->pipe->conn->security_state.generic_state, 384 &s->gensec_skey); 385 if (!NT_STATUS_IS_OK(status)) { 386 PyErr_Format(PyExc_RuntimeError, "Unable to get session key from drspipe: %s", 387 nt_errstr(status)); 388 talloc_free(s); 389 return NULL; 390 } 391 392 s->forest.dns_name = lpcfg_dnsdomain(lp); 393 394 s->chunk.gensec_skey = &s->gensec_skey; 395 s->chunk.partition = &s->partition; 396 s->chunk.forest = &s->forest; 397 s->chunk.dest_dsa = &s->dest_dsa; 398 399 return PyCObject_FromTallocPtr(s); 400 } 401 402 403 /* 404 process one replication chunk 405 */ 406 static PyObject *py_net_replicate_chunk(py_net_Object *self, PyObject *args, PyObject *kwargs) 407 { 408 const char *kwnames[] = { "state", "level", "ctr", "schema", NULL }; 409 PyObject *py_state, *py_ctr, *py_schema; 410 struct replicate_state *s; 411 unsigned level; 412 NTSTATUS (*chunk_handler)(void *private_data, const struct libnet_BecomeDC_StoreChunk *c); 413 NTSTATUS status; 414 415 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OIO|O", 416 discard_const_p(char *, kwnames), 417 &py_state, &level, &py_ctr, &py_schema)) { 418 return NULL; 419 } 420 421 s = talloc_get_type(PyCObject_AsVoidPtr(py_state), struct replicate_state); 422 if (!s) { 423 PyErr_SetString(PyExc_TypeError, "Expected replication_state"); 424 return NULL; 425 } 426 427 switch (level) { 428 case 1: 429 if (!py_check_dcerpc_type(py_ctr, "samba.dcerpc.drsuapi", "DsGetNCChangesCtr1")) { 430 return NULL; 431 } 432 s->chunk.ctr1 = py_talloc_get_ptr(py_ctr); 433 s->partition.nc = *s->chunk.ctr1->naming_context; 434 s->partition.more_data = s->chunk.ctr1->more_data; 435 s->partition.source_dsa_guid = s->chunk.ctr1->source_dsa_guid; 436 s->partition.source_dsa_invocation_id = s->chunk.ctr1->source_dsa_invocation_id; 437 s->partition.highwatermark = s->chunk.ctr1->new_highwatermark; 438 break; 439 case 6: 440 if (!py_check_dcerpc_type(py_ctr, "samba.dcerpc.drsuapi", "DsGetNCChangesCtr6")) { 441 return NULL; 442 } 443 s->chunk.ctr6 = py_talloc_get_ptr(py_ctr); 444 s->partition.nc = *s->chunk.ctr6->naming_context; 445 s->partition.more_data = s->chunk.ctr6->more_data; 446 s->partition.source_dsa_guid = s->chunk.ctr6->source_dsa_guid; 447 s->partition.source_dsa_invocation_id = s->chunk.ctr6->source_dsa_invocation_id; 448 s->partition.highwatermark = s->chunk.ctr6->new_highwatermark; 449 break; 450 default: 451 PyErr_Format(PyExc_TypeError, "Bad level %u in replicate_chunk", level); 452 return NULL; 453 } 454 455 chunk_handler = libnet_vampire_cb_store_chunk; 456 if (py_schema) { 457 if (!PyBool_Check(py_schema)) { 458 PyErr_SetString(PyExc_TypeError, "Expected boolean schema"); 459 return NULL; 460 } 461 if (py_schema == Py_True) { 462 chunk_handler = libnet_vampire_cb_schema_chunk; 463 } 464 } 465 466 s->chunk.ctr_level = level; 467 468 status = chunk_handler(s->vampire_state, &s->chunk); 469 if (!NT_STATUS_IS_OK(status)) { 470 PyErr_Format(PyExc_TypeError, "Failed to process chunk: %s", nt_errstr(status)); 471 return NULL; 472 } 473 474 Py_RETURN_NONE; 475 } 476 477 478 /* 479 find a DC given a domain name and server type 480 */ 481 static PyObject *py_net_finddc(py_net_Object *self, PyObject *args) 482 { 483 const char *domain_name; 484 unsigned server_type; 485 NTSTATUS status; 486 struct finddcs *io; 487 TALLOC_CTX *mem_ctx; 488 PyObject *ret; 489 490 if (!PyArg_ParseTuple(args, "sI", &domain_name, &server_type)) { 491 return NULL; 492 } 493 494 mem_ctx = talloc_new(self->mem_ctx); 495 496 io = talloc_zero(mem_ctx, struct finddcs); 497 io->in.domain_name = domain_name; 498 io->in.minimum_dc_flags = server_type; 499 500 status = finddcs_cldap(io, io, 501 lpcfg_resolve_context(self->libnet_ctx->lp_ctx), self->ev); 502 if (NT_STATUS_IS_ERR(status)) { 503 PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); 504 talloc_free(mem_ctx); 505 return NULL; 506 } 507 508 ret = py_return_ndr_struct("samba.dcerpc.nbt", "NETLOGON_SAM_LOGON_RESPONSE_EX", 509 io, &io->out.netlogon.data.nt5_ex); 510 talloc_free(mem_ctx); 511 512 return ret; 513 } 514 515 516 static const char py_net_vampire_doc[] = "vampire(domain, target_dir=None)\n" 517 "Vampire a domain."; 518 519 static const char py_net_replicate_init_doc[] = "replicate_init(samdb, lp, drspipe)\n" 520 "Setup for replicate_chunk calls."; 521 522 static const char py_net_replicate_chunk_doc[] = "replicate_chunk(state, level, ctr, schema)\n" 523 "Process replication for one chunk"; 524 525 static const char py_net_finddc_doc[] = "finddc(domain, server_type)\n" 526 "find a DC with the specified server_type bits. Return the DNS name"; 527 528 static PyMethodDef net_obj_methods[] = { 529 {"join", (PyCFunction)py_net_join, METH_VARARGS|METH_KEYWORDS, py_net_join_doc}, 530 {"set_password", (PyCFunction)py_net_set_password, METH_VARARGS|METH_KEYWORDS, py_net_set_password_doc}, 531 {"export_keytab", (PyCFunction)py_net_export_keytab, METH_VARARGS|METH_KEYWORDS, py_net_export_keytab_doc}, 532 {"time", (PyCFunction)py_net_time, METH_VARARGS|METH_KEYWORDS, py_net_time_doc}, 533 {"create_user", (PyCFunction)py_net_user_create, METH_VARARGS|METH_KEYWORDS, py_net_create_user_doc}, 534 {"delete_user", (PyCFunction)py_net_user_delete, METH_VARARGS|METH_KEYWORDS, py_net_delete_user_doc}, 535 {"vampire", (PyCFunction)py_net_vampire, METH_VARARGS|METH_KEYWORDS, py_net_vampire_doc}, 536 {"replicate_init", (PyCFunction)py_net_replicate_init, METH_VARARGS|METH_KEYWORDS, py_net_replicate_init_doc}, 537 {"replicate_chunk", (PyCFunction)py_net_replicate_chunk, METH_VARARGS|METH_KEYWORDS, py_net_replicate_chunk_doc}, 538 {"finddc", (PyCFunction)py_net_finddc, METH_VARARGS, py_net_finddc_doc}, 539 { NULL } 540 }; 541 542 static void py_net_dealloc(py_net_Object *self) 543 { 544 talloc_free(self->mem_ctx); 545 PyObject_Del(self); 546 } 547 548 static PyObject *net_obj_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) 549 { 550 PyObject *py_creds, *py_lp = Py_None; 551 const char *kwnames[] = { "creds", "lp", "server", NULL }; 552 py_net_Object *ret; 553 struct loadparm_context *lp; 554 const char *server_address = NULL; 555 556 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oz", 557 discard_const_p(char *, kwnames), &py_creds, &py_lp, 558 &server_address)) 559 return NULL; 560 561 ret = PyObject_New(py_net_Object, type); 562 if (ret == NULL) { 563 return NULL; 564 } 565 566 /* FIXME: we really need to get a context from the caller or we may end 567 * up with 2 event contexts */ 568 ret->ev = s4_event_context_init(NULL); 569 ret->mem_ctx = talloc_new(ret->ev); 570 571 lp = lpcfg_from_py_object(ret->mem_ctx, py_lp); 572 if (lp == NULL) { 573 Py_DECREF(ret); 574 return NULL; 575 } 576 577 ret->libnet_ctx = libnet_context_init(ret->ev, lp); 578 if (ret->libnet_ctx == NULL) { 579 PyErr_SetString(PyExc_RuntimeError, "Unable to initialize net"); 580 Py_DECREF(ret); 581 return NULL; 582 } 583 584 ret->libnet_ctx->server_address = server_address; 585 586 ret->libnet_ctx->cred = cli_credentials_from_py_object(py_creds); 587 if (ret->libnet_ctx->cred == NULL) { 67 588 PyErr_SetString(PyExc_TypeError, "Expected credentials object"); 68 return NULL; 69 } 70 71 libnet_ctx = py_net_ctx(cls, ev, creds); 72 73 status = libnet_Join(libnet_ctx, mem_ctx, &r); 74 if (NT_STATUS_IS_ERR(status)) { 75 PyErr_SetString(PyExc_RuntimeError, r.out.error_string); 76 talloc_free(mem_ctx); 77 return NULL; 78 } 79 80 result = Py_BuildValue("sss", r.out.join_password, 81 dom_sid_string(mem_ctx, r.out.domain_sid), 82 r.out.domain_name); 83 84 talloc_free(mem_ctx); 85 86 if (result == NULL) 87 return NULL; 88 89 return result; 90 } 91 92 static char py_net_join_doc[] = "join(domain_name, netbios_name, join_type, level) -> (join_password, domain_sid, domain_name)\n\n" \ 93 "Join the domain with the specified name."; 94 95 static struct PyMethodDef net_methods[] = { 96 {"Join", (PyCFunction)py_net_join, METH_VARARGS|METH_KEYWORDS, py_net_join_doc}, 97 {NULL } 589 Py_DECREF(ret); 590 return NULL; 591 } 592 593 return (PyObject *)ret; 594 } 595 596 597 PyTypeObject py_net_Type = { 598 PyObject_HEAD_INIT(NULL) 0, 599 .tp_name = "net.Net", 600 .tp_basicsize = sizeof(py_net_Object), 601 .tp_dealloc = (destructor)py_net_dealloc, 602 .tp_methods = net_obj_methods, 603 .tp_new = net_obj_new, 98 604 }; 99 605 100 606 void initnet(void) 101 607 { 102 Py_InitModule("net", net_methods); 103 } 608 PyObject *m; 609 610 if (PyType_Ready(&py_net_Type) < 0) 611 return; 612 613 m = Py_InitModule3("net", NULL, NULL); 614 if (m == NULL) 615 return; 616 617 Py_INCREF(&py_net_Type); 618 PyModule_AddObject(m, "Net", (PyObject *)&py_net_Type); 619 PyModule_AddObject(m, "LIBNET_JOINDOMAIN_AUTOMATIC", PyInt_FromLong(LIBNET_JOINDOMAIN_AUTOMATIC)); 620 PyModule_AddObject(m, "LIBNET_JOINDOMAIN_SPECIFIED", PyInt_FromLong(LIBNET_JOINDOMAIN_SPECIFIED)); 621 PyModule_AddObject(m, "LIBNET_JOIN_AUTOMATIC", PyInt_FromLong(LIBNET_JOIN_AUTOMATIC)); 622 PyModule_AddObject(m, "LIBNET_JOIN_SPECIFIED", PyInt_FromLong(LIBNET_JOIN_SPECIFIED)); 623 }
Note:
See TracChangeset
for help on using the changeset viewer.