2 Unix SMB/CIFS implementation.
4 endpoint server for the samr pipe
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "librpc/gen_ndr/ndr_samr.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "rpc_server/samr/dcesrv_samr.h"
28 #include "system/time.h"
29 #include "lib/ldb/include/ldb.h"
33 destroy a general handle.
35 static void samr_handle_destroy(struct dcesrv_connection
*conn
, struct dcesrv_handle
*h
)
43 create a connection to the SAM database
45 static NTSTATUS
samr_Connect(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
46 struct samr_Connect
*r
)
48 struct samr_connect_state
*c_state
;
49 struct dcesrv_handle
*handle
;
51 ZERO_STRUCTP(r
->out
.connect_handle
);
53 c_state
= talloc_p(dce_call
->conn
, struct samr_connect_state
);
55 return NT_STATUS_NO_MEMORY
;
58 /* make sure the sam database is accessible */
59 c_state
->sam_ctx
= samdb_connect(c_state
);
60 if (c_state
->sam_ctx
== NULL
) {
62 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
65 handle
= dcesrv_handle_new(dce_call
->conn
, SAMR_HANDLE_CONNECT
);
68 return NT_STATUS_NO_MEMORY
;
71 handle
->data
= c_state
;
72 handle
->destroy
= samr_handle_destroy
;
74 c_state
->access_mask
= r
->in
.access_mask
;
75 *r
->out
.connect_handle
= handle
->wire_handle
;
84 static NTSTATUS
samr_Close(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
87 struct dcesrv_handle
*h
;
89 *r
->out
.handle
= *r
->in
.handle
;
91 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, DCESRV_HANDLE_ANY
);
93 /* this causes the parameters samr_XXX_destroy() to be called by
94 the handle destroy code which destroys the state associated
96 dcesrv_handle_destroy(dce_call
->conn
, h
);
98 ZERO_STRUCTP(r
->out
.handle
);
107 static NTSTATUS
samr_SetSecurity(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
108 struct samr_SetSecurity
*r
)
110 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
117 static NTSTATUS
samr_QuerySecurity(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
118 struct samr_QuerySecurity
*r
)
120 struct dcesrv_handle
*h
;
121 struct sec_desc_buf
*sd
;
125 DCESRV_PULL_HANDLE(h
, r
->in
.handle
, DCESRV_HANDLE_ANY
);
127 sd
= talloc_p(mem_ctx
, struct sec_desc_buf
);
129 return NT_STATUS_NO_MEMORY
;
132 sd
->sd
= samdb_default_security_descriptor(mem_ctx
);
143 we refuse this operation completely. If a admin wants to shutdown samr
144 in Samba then they should use the samba admin tools to disable the samr pipe
146 static NTSTATUS
samr_Shutdown(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
147 struct samr_Shutdown
*r
)
149 return NT_STATUS_ACCESS_DENIED
;
156 this maps from a domain name to a SID
158 static NTSTATUS
samr_LookupDomain(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
159 struct samr_LookupDomain
*r
)
161 struct samr_connect_state
*c_state
;
162 struct dcesrv_handle
*h
;
163 struct dom_sid2
*sid
;
168 DCESRV_PULL_HANDLE(h
, r
->in
.connect_handle
, SAMR_HANDLE_CONNECT
);
172 if (r
->in
.domain
->string
== NULL
) {
173 return NT_STATUS_INVALID_PARAMETER
;
176 sidstr
= samdb_search_string(c_state
->sam_ctx
,
177 mem_ctx
, NULL
, "objectSid",
178 "(&(name=%s)(objectclass=domain))",
179 r
->in
.domain
->string
);
180 if (sidstr
== NULL
) {
181 return NT_STATUS_NO_SUCH_DOMAIN
;
184 sid
= dom_sid_parse_talloc(mem_ctx
, sidstr
);
186 DEBUG(0,("samdb: Invalid sid '%s' for domain %s\n",
187 sidstr
, r
->in
.domain
->string
));
188 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
200 list the domains in the SAM
202 static NTSTATUS
samr_EnumDomains(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
203 struct samr_EnumDomains
*r
)
205 struct samr_connect_state
*c_state
;
206 struct dcesrv_handle
*h
;
207 struct samr_SamArray
*array
;
208 const char **domains
;
209 int count
, i
, start_i
;
211 *r
->out
.resume_handle
= 0;
213 r
->out
.num_entries
= 0;
215 DCESRV_PULL_HANDLE(h
, r
->in
.connect_handle
, SAMR_HANDLE_CONNECT
);
219 count
= samdb_search_string_multiple(c_state
->sam_ctx
,
220 mem_ctx
, NULL
, &domains
,
221 "name", "(objectclass=domain)");
223 DEBUG(0,("samdb: no domains found in EnumDomains\n"));
224 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
227 *r
->out
.resume_handle
= count
;
229 start_i
= *r
->in
.resume_handle
;
231 if (start_i
>= count
) {
232 /* search past end of list is not an error for this call */
236 array
= talloc_p(mem_ctx
, struct samr_SamArray
);
238 return NT_STATUS_NO_MEMORY
;
242 array
->entries
= NULL
;
244 array
->entries
= talloc_array_p(mem_ctx
, struct samr_SamEntry
, count
- start_i
);
245 if (array
->entries
== NULL
) {
246 return NT_STATUS_NO_MEMORY
;
249 for (i
=0;i
<count
-start_i
;i
++) {
250 array
->entries
[i
].idx
= start_i
+ i
;
251 array
->entries
[i
].name
.string
= domains
[start_i
+i
];
255 r
->out
.num_entries
= i
;
256 array
->count
= r
->out
.num_entries
;
265 static NTSTATUS
samr_OpenDomain(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
266 struct samr_OpenDomain
*r
)
268 struct dcesrv_handle
*h_conn
, *h_domain
;
269 const char *sidstr
, *domain_name
;
270 struct samr_connect_state
*c_state
;
271 struct samr_domain_state
*d_state
;
272 const char * const attrs
[2] = { "name", NULL
};
273 struct ldb_message
**msgs
;
276 ZERO_STRUCTP(r
->out
.domain_handle
);
278 DCESRV_PULL_HANDLE(h_conn
, r
->in
.connect_handle
, SAMR_HANDLE_CONNECT
);
280 c_state
= h_conn
->data
;
282 if (r
->in
.sid
== NULL
) {
283 return NT_STATUS_INVALID_PARAMETER
;
286 sidstr
= dom_sid_string(mem_ctx
, r
->in
.sid
);
287 if (sidstr
== NULL
) {
288 return NT_STATUS_INVALID_PARAMETER
;
291 ret
= samdb_search(c_state
->sam_ctx
,
292 mem_ctx
, NULL
, &msgs
, attrs
,
293 "(&(objectSid=%s)(objectclass=domain))",
296 return NT_STATUS_NO_SUCH_DOMAIN
;
299 domain_name
= ldb_msg_find_string(msgs
[0], "name", NULL
);
300 if (domain_name
== NULL
) {
301 return NT_STATUS_NO_SUCH_DOMAIN
;
304 d_state
= talloc_p(c_state
, struct samr_domain_state
);
306 return NT_STATUS_NO_MEMORY
;
309 d_state
->connect_state
= talloc_reference(d_state
, c_state
);
310 d_state
->sam_ctx
= c_state
->sam_ctx
;
311 d_state
->domain_sid
= talloc_strdup(d_state
, sidstr
);
312 d_state
->domain_name
= talloc_strdup(d_state
, domain_name
);
313 d_state
->domain_dn
= talloc_strdup(d_state
, msgs
[0]->dn
);
314 if (!d_state
->domain_sid
|| !d_state
->domain_name
|| !d_state
->domain_dn
) {
315 talloc_free(d_state
);
316 return NT_STATUS_NO_MEMORY
;
318 d_state
->access_mask
= r
->in
.access_mask
;
320 h_domain
= dcesrv_handle_new(dce_call
->conn
, SAMR_HANDLE_DOMAIN
);
322 talloc_free(d_state
);
323 return NT_STATUS_NO_MEMORY
;
326 h_domain
->data
= d_state
;
327 h_domain
->destroy
= samr_handle_destroy
;
328 *r
->out
.domain_handle
= h_domain
->wire_handle
;
336 static NTSTATUS
samr_info_DomInfo2(struct samr_domain_state
*state
, TALLOC_CTX
*mem_ctx
,
337 struct samr_DomInfo2
*info
)
339 const char * const attrs
[] = { "comment", "name", NULL
};
341 struct ldb_message
**res
;
343 ret
= samdb_search(state
->sam_ctx
, mem_ctx
, NULL
, &res
, attrs
,
344 "dn=%s", state
->domain_dn
);
346 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
349 /* where is this supposed to come from? is it settable? */
350 info
->force_logoff_time
= 0x8000000000000000LL
;
352 info
->comment
.string
= samdb_result_string(res
[0], "comment", NULL
);
353 info
->domain
.string
= samdb_result_string(res
[0], "name", NULL
);
355 info
->primary
.string
= lp_netbios_name();
356 info
->sequence_num
= 0;
357 info
->role
= ROLE_DOMAIN_PDC
;
358 info
->num_users
= samdb_search_count(state
->sam_ctx
, mem_ctx
, NULL
, "(objectClass=user)");
359 info
->num_groups
= samdb_search_count(state
->sam_ctx
, mem_ctx
, NULL
,
360 "(&(objectClass=group)(sAMAccountType=%u))",
362 info
->num_aliases
= samdb_search_count(state
->sam_ctx
, mem_ctx
, NULL
,
363 "(&(objectClass=group)(sAMAccountType=%u))",
372 static NTSTATUS
samr_QueryDomainInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
373 struct samr_QueryDomainInfo
*r
)
375 struct dcesrv_handle
*h
;
376 struct samr_domain_state
*d_state
;
380 DCESRV_PULL_HANDLE(h
, r
->in
.domain_handle
, SAMR_HANDLE_DOMAIN
);
384 r
->out
.info
= talloc_p(mem_ctx
, union samr_DomainInfo
);
386 return NT_STATUS_NO_MEMORY
;
389 ZERO_STRUCTP(r
->out
.info
);
391 switch (r
->in
.level
) {
393 return samr_info_DomInfo2(d_state
, mem_ctx
, &r
->out
.info
->info2
);
396 return NT_STATUS_INVALID_INFO_CLASS
;
403 static NTSTATUS
samr_SetDomainInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
404 struct samr_SetDomainInfo
*r
)
406 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
410 samr_CreateDomainGroup
412 static NTSTATUS
samr_CreateDomainGroup(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
413 struct samr_CreateDomainGroup
*r
)
415 struct samr_domain_state
*d_state
;
416 struct samr_account_state
*a_state
;
417 struct dcesrv_handle
*h
;
419 struct ldb_message msg
;
421 const char *groupname
, *sidstr
, *guidstr
;
423 time_t now
= time(NULL
);
424 struct dcesrv_handle
*g_handle
;
428 ZERO_STRUCTP(r
->out
.group_handle
);
431 DCESRV_PULL_HANDLE(h
, r
->in
.domain_handle
, SAMR_HANDLE_DOMAIN
);
435 groupname
= r
->in
.name
->string
;
437 if (groupname
== NULL
) {
438 return NT_STATUS_INVALID_PARAMETER
;
441 /* check if the group already exists */
442 name
= samdb_search_string(d_state
->sam_ctx
, mem_ctx
, NULL
,
444 "(&(sAMAccountName=%s)(objectclass=group))",
447 return NT_STATUS_GROUP_EXISTS
;
452 /* pull in all the template attributes */
453 ret
= samdb_copy_template(d_state
->sam_ctx
, mem_ctx
, &msg
,
454 "(&(name=TemplateGroup)(objectclass=groupTemplate))");
456 DEBUG(0,("Failed to load TemplateGroup from samdb\n"));
457 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
461 status
= samdb_allocate_next_id(d_state
->sam_ctx
, mem_ctx
,
462 d_state
->domain_dn
, "nextRid", &rid
);
463 if (!NT_STATUS_IS_OK(status
)) {
467 /* and the group SID */
468 sidstr
= talloc_asprintf(mem_ctx
, "%s-%u", d_state
->domain_sid
, rid
);
470 return NT_STATUS_NO_MEMORY
;
474 guid
= GUID_random();
475 guidstr
= GUID_string(mem_ctx
, &guid
);
477 return NT_STATUS_NO_MEMORY
;
480 /* add core elements to the ldb_message for the user */
481 msg
.dn
= talloc_asprintf(mem_ctx
, "CN=%s,CN=Users,%s", groupname
,
484 return NT_STATUS_NO_MEMORY
;
486 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "name", groupname
);
487 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "cn", groupname
);
488 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "sAMAccountName", groupname
);
489 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "objectClass", "group");
490 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "objectSid", sidstr
);
491 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "objectGUID", guidstr
);
492 samdb_msg_set_ldaptime(d_state
->sam_ctx
, mem_ctx
, &msg
, "whenCreated", now
);
493 samdb_msg_set_ldaptime(d_state
->sam_ctx
, mem_ctx
, &msg
, "whenChanged", now
);
495 /* create the group */
496 ret
= samdb_add(d_state
->sam_ctx
, mem_ctx
, &msg
);
498 DEBUG(0,("Failed to create group record %s\n", msg
.dn
));
499 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
502 a_state
= talloc_p(d_state
, struct samr_account_state
);
504 return NT_STATUS_NO_MEMORY
;
506 a_state
->sam_ctx
= d_state
->sam_ctx
;
507 a_state
->access_mask
= r
->in
.access_mask
;
508 a_state
->domain_state
= talloc_reference(a_state
, d_state
);
509 a_state
->account_dn
= talloc_steal(d_state
, msg
.dn
);
510 a_state
->account_sid
= talloc_strdup(d_state
, sidstr
);
511 a_state
->account_name
= talloc_strdup(d_state
, groupname
);
512 if (!a_state
->account_name
|| !a_state
->account_sid
) {
513 talloc_free(a_state
);
514 return NT_STATUS_NO_MEMORY
;
517 /* create the policy handle */
518 g_handle
= dcesrv_handle_new(dce_call
->conn
, SAMR_HANDLE_GROUP
);
520 return NT_STATUS_NO_MEMORY
;
523 g_handle
->data
= a_state
;
524 g_handle
->destroy
= samr_handle_destroy
;
526 *r
->out
.group_handle
= g_handle
->wire_handle
;
534 samr_EnumDomainGroups
536 static NTSTATUS
samr_EnumDomainGroups(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
537 struct samr_EnumDomainGroups
*r
)
539 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
546 TODO: This should do some form of locking, especially around the rid allocation
548 static NTSTATUS
samr_CreateUser2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
549 struct samr_CreateUser2
*r
)
551 struct samr_domain_state
*d_state
;
552 struct samr_account_state
*a_state
;
553 struct dcesrv_handle
*h
;
555 struct ldb_message msg
;
557 const char *account_name
, *sidstr
, *guidstr
;
559 time_t now
= time(NULL
);
560 struct dcesrv_handle
*u_handle
;
563 const char *container
, *additional_class
=NULL
;
565 ZERO_STRUCTP(r
->out
.user_handle
);
566 *r
->out
.access_granted
= 0;
569 DCESRV_PULL_HANDLE(h
, r
->in
.domain_handle
, SAMR_HANDLE_DOMAIN
);
573 account_name
= r
->in
.account_name
->string
;
575 if (account_name
== NULL
) {
576 return NT_STATUS_INVALID_PARAMETER
;
579 /* check if the user already exists */
580 name
= samdb_search_string(d_state
->sam_ctx
, mem_ctx
, NULL
,
582 "(&(sAMAccountName=%s)(objectclass=user))", account_name
);
584 return NT_STATUS_USER_EXISTS
;
589 /* This must be one of these values *only* */
590 if (r
->in
.acct_flags
== ACB_NORMAL
) {
591 /* pull in all the template attributes */
592 ret
= samdb_copy_template(d_state
->sam_ctx
, mem_ctx
, &msg
,
593 "(&(name=TemplateUser)(objectclass=userTemplate))");
595 DEBUG(0,("Failed to load TemplateUser from samdb\n"));
596 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
601 } else if (r
->in
.acct_flags
== ACB_WSTRUST
) {
602 /* pull in all the template attributes */
603 ret
= samdb_copy_template(d_state
->sam_ctx
, mem_ctx
, &msg
,
604 "(&(name=TemplateMemberServer)(objectclass=userTemplate))");
606 DEBUG(0,("Failed to load TemplateMemberServer from samdb\n"));
607 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
610 container
= "Computers";
611 additional_class
= "computer";
613 } else if (r
->in
.acct_flags
== ACB_SVRTRUST
) {
614 /* pull in all the template attributes */
615 ret
= samdb_copy_template(d_state
->sam_ctx
, mem_ctx
, &msg
,
616 "(&(name=TemplateDomainController)(objectclass=userTemplate))");
618 DEBUG(0,("Failed to load TemplateDomainController from samdb\n"));
619 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
622 container
= "Domain Controllers";
623 additional_class
= "computer";
625 } else if (r
->in
.acct_flags
== ACB_DOMTRUST
) {
626 /* pull in all the template attributes */
627 ret
= samdb_copy_template(d_state
->sam_ctx
, mem_ctx
, &msg
,
628 "(&(name=TemplateTrustingDomain)(objectclass=userTemplate))");
630 DEBUG(0,("Failed to load TemplateTrustingDomain from samdb\n"));
631 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
635 additional_class
= "computer";
638 return NT_STATUS_INVALID_PARAMETER
;
642 status
= samdb_allocate_next_id(d_state
->sam_ctx
, mem_ctx
,
643 d_state
->domain_dn
, "nextRid", &rid
);
644 if (!NT_STATUS_IS_OK(status
)) {
648 /* and the users SID */
649 sidstr
= talloc_asprintf(mem_ctx
, "%s-%u", d_state
->domain_sid
, rid
);
651 return NT_STATUS_NO_MEMORY
;
655 guid
= GUID_random();
656 guidstr
= GUID_string(mem_ctx
, &guid
);
658 return NT_STATUS_NO_MEMORY
;
661 /* add core elements to the ldb_message for the user */
662 msg
.dn
= talloc_asprintf(mem_ctx
, "CN=%s,CN=%s,%s", account_name
, container
, d_state
->domain_dn
);
664 return NT_STATUS_NO_MEMORY
;
666 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "name", account_name
);
667 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "cn", account_name
);
668 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "sAMAccountName", account_name
);
669 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "objectClass", "user");
670 if (additional_class
) {
671 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "objectClass", additional_class
);
673 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "objectSid", sidstr
);
674 samdb_msg_add_string(d_state
->sam_ctx
, mem_ctx
, &msg
, "objectGUID", guidstr
);
675 samdb_msg_set_ldaptime(d_state
->sam_ctx
, mem_ctx
, &msg
, "whenCreated", now
);
676 samdb_msg_set_ldaptime(d_state
->sam_ctx
, mem_ctx
, &msg
, "whenChanged", now
);
678 /* create the user */
679 ret
= samdb_add(d_state
->sam_ctx
, mem_ctx
, &msg
);
681 DEBUG(0,("Failed to create user record %s\n", msg
.dn
));
682 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
685 a_state
= talloc_p(d_state
, struct samr_account_state
);
687 return NT_STATUS_NO_MEMORY
;
689 a_state
->sam_ctx
= d_state
->sam_ctx
;
690 a_state
->access_mask
= r
->in
.access_mask
;
691 a_state
->domain_state
= talloc_reference(a_state
, d_state
);
692 a_state
->account_dn
= talloc_steal(d_state
, msg
.dn
);
693 a_state
->account_sid
= talloc_strdup(d_state
, sidstr
);
694 a_state
->account_name
= talloc_strdup(d_state
, account_name
);
695 if (!a_state
->account_name
|| !a_state
->account_sid
) {
696 talloc_free(a_state
);
697 return NT_STATUS_NO_MEMORY
;
700 /* create the policy handle */
701 u_handle
= dcesrv_handle_new(dce_call
->conn
, SAMR_HANDLE_USER
);
703 talloc_free(a_state
);
704 return NT_STATUS_NO_MEMORY
;
707 u_handle
->data
= a_state
;
708 u_handle
->destroy
= samr_handle_destroy
;
710 /* the domain state is in use one more time */
713 *r
->out
.user_handle
= u_handle
->wire_handle
;
714 *r
->out
.access_granted
= 0xf07ff; /* TODO: fix access mask calculations */
724 static NTSTATUS
samr_CreateUser(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
725 struct samr_CreateUser
*r
)
727 struct samr_CreateUser2 r2
;
728 uint32_t access_granted
= 0;
731 /* a simple wrapper around samr_CreateUser2 works nicely */
732 r2
.in
.domain_handle
= r
->in
.domain_handle
;
733 r2
.in
.account_name
= r
->in
.account_name
;
734 r2
.in
.acct_flags
= ACB_NORMAL
;
735 r2
.in
.access_mask
= r
->in
.access_mask
;
736 r2
.out
.user_handle
= r
->out
.user_handle
;
737 r2
.out
.access_granted
= &access_granted
;
738 r2
.out
.rid
= r
->out
.rid
;
740 return samr_CreateUser2(dce_call
, mem_ctx
, &r2
);
744 comparison function for sorting SamEntry array
746 static int compare_SamEntry(struct samr_SamEntry
*e1
, struct samr_SamEntry
*e2
)
748 return e1
->idx
- e2
->idx
;
754 static NTSTATUS
samr_EnumDomainUsers(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
755 struct samr_EnumDomainUsers
*r
)
757 struct dcesrv_handle
*h
;
758 struct samr_domain_state
*d_state
;
759 struct ldb_message
**res
;
761 struct samr_SamEntry
*entries
;
762 const char * const attrs
[3] = { "objectSid", "sAMAccountName", NULL
};
764 *r
->out
.resume_handle
= 0;
766 r
->out
.num_entries
= 0;
768 DCESRV_PULL_HANDLE(h
, r
->in
.domain_handle
, SAMR_HANDLE_DOMAIN
);
772 /* search for all users in this domain. This could possibly be cached and
773 resumed based on resume_key */
774 count
= samdb_search(d_state
->sam_ctx
, mem_ctx
, d_state
->domain_dn
, &res
, attrs
,
777 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
779 if (count
== 0 || r
->in
.max_size
== 0) {
783 /* convert to SamEntry format */
784 entries
= talloc_array_p(mem_ctx
, struct samr_SamEntry
, count
);
786 return NT_STATUS_NO_MEMORY
;
788 for (i
=0;i
<count
;i
++) {
789 entries
[i
].idx
= samdb_result_rid_from_sid(mem_ctx
, res
[i
], "objectSid", 0);
790 entries
[i
].name
.string
= samdb_result_string(res
[i
], "sAMAccountName", "");
793 /* sort the results by rid */
794 qsort(entries
, count
, sizeof(struct samr_SamEntry
),
795 (comparison_fn_t
)compare_SamEntry
);
797 /* find the first entry to return */
799 first
<count
&& entries
[first
].idx
<= *r
->in
.resume_handle
;
802 if (first
== count
) {
806 /* return the rest, limit by max_size. Note that we
807 use the w2k3 element size value of 54 */
808 r
->out
.num_entries
= count
- first
;
809 r
->out
.num_entries
= MIN(r
->out
.num_entries
,
810 1+(r
->in
.max_size
/SAMR_ENUM_USERS_MULTIPLIER
));
812 r
->out
.sam
= talloc_p(mem_ctx
, struct samr_SamArray
);
814 return NT_STATUS_NO_MEMORY
;
817 r
->out
.sam
->entries
= entries
+first
;
818 r
->out
.sam
->count
= r
->out
.num_entries
;
820 if (r
->out
.num_entries
< count
- first
) {
821 *r
->out
.resume_handle
= entries
[first
+r
->out
.num_entries
-1].idx
;
822 return STATUS_MORE_ENTRIES
;
832 static NTSTATUS
samr_CreateDomAlias(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
833 struct samr_CreateDomAlias
*r
)
835 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
840 samr_EnumDomainAliases
842 static NTSTATUS
samr_EnumDomainAliases(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
843 struct samr_EnumDomainAliases
*r
)
845 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
850 samr_GetAliasMembership
852 static NTSTATUS
samr_GetAliasMembership(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
853 struct samr_GetAliasMembership
*r
)
855 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
862 static NTSTATUS
samr_LookupNames(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
863 struct samr_LookupNames
*r
)
865 struct dcesrv_handle
*h
;
866 struct samr_domain_state
*d_state
;
868 NTSTATUS status
= NT_STATUS_OK
;
869 const char * const attrs
[] = { "sAMAccountType", "objectSid", NULL
};
872 ZERO_STRUCT(r
->out
.rids
);
873 ZERO_STRUCT(r
->out
.types
);
875 DCESRV_PULL_HANDLE(h
, r
->in
.domain_handle
, SAMR_HANDLE_DOMAIN
);
879 if (r
->in
.num_names
== 0) {
883 r
->out
.rids
.ids
= talloc_array_p(mem_ctx
, uint32_t, r
->in
.num_names
);
884 r
->out
.types
.ids
= talloc_array_p(mem_ctx
, uint32_t, r
->in
.num_names
);
885 if (!r
->out
.rids
.ids
|| !r
->out
.types
.ids
) {
886 return NT_STATUS_NO_MEMORY
;
888 r
->out
.rids
.count
= r
->in
.num_names
;
889 r
->out
.types
.count
= r
->in
.num_names
;
891 for (i
=0;i
<r
->in
.num_names
;i
++) {
892 struct ldb_message
**res
;
893 struct dom_sid2
*sid
;
895 uint32_t atype
, rtype
;
897 r
->out
.rids
.ids
[i
] = 0;
898 r
->out
.types
.ids
[i
] = SID_NAME_UNKNOWN
;
900 count
= samdb_search(d_state
->sam_ctx
, mem_ctx
, d_state
->domain_dn
, &res
, attrs
,
901 "sAMAccountName=%s", r
->in
.names
[i
].string
);
903 status
= STATUS_SOME_UNMAPPED
;
907 sidstr
= samdb_result_string(res
[0], "objectSid", NULL
);
908 if (sidstr
== NULL
) {
909 status
= STATUS_SOME_UNMAPPED
;
913 sid
= dom_sid_parse_talloc(mem_ctx
, sidstr
);
915 status
= STATUS_SOME_UNMAPPED
;
919 atype
= samdb_result_uint(res
[0], "sAMAccountType", 0);
921 status
= STATUS_SOME_UNMAPPED
;
925 rtype
= samdb_atype_map(atype
);
927 if (rtype
== SID_NAME_UNKNOWN
) {
928 status
= STATUS_SOME_UNMAPPED
;
932 r
->out
.rids
.ids
[i
] = sid
->sub_auths
[sid
->num_auths
-1];
933 r
->out
.types
.ids
[i
] = rtype
;
944 static NTSTATUS
samr_LookupRids(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
945 struct samr_LookupRids
*r
)
947 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
954 static NTSTATUS
samr_OpenGroup(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
955 struct samr_OpenGroup
*r
)
957 struct samr_domain_state
*d_state
;
958 struct samr_account_state
*a_state
;
959 struct dcesrv_handle
*h
;
960 const char *groupname
, *sidstr
;
961 struct ldb_message
**msgs
;
962 struct dcesrv_handle
*g_handle
;
963 const char * const attrs
[2] = { "sAMAccountName", NULL
};
966 ZERO_STRUCTP(r
->out
.group_handle
);
968 DCESRV_PULL_HANDLE(h
, r
->in
.domain_handle
, SAMR_HANDLE_DOMAIN
);
972 /* form the group SID */
973 sidstr
= talloc_asprintf(mem_ctx
, "%s-%u", d_state
->domain_sid
, r
->in
.rid
);
975 return NT_STATUS_NO_MEMORY
;
978 /* search for the group record */
979 ret
= samdb_search(d_state
->sam_ctx
,
980 mem_ctx
, d_state
->domain_dn
, &msgs
, attrs
,
981 "(&(objectSid=%s)(objectclass=group))",
984 return NT_STATUS_NO_SUCH_GROUP
;
987 DEBUG(0,("Found %d records matching sid %s\n", ret
, sidstr
));
988 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
991 groupname
= samdb_result_string(msgs
[0], "sAMAccountName", NULL
);
992 if (groupname
== NULL
) {
993 DEBUG(0,("sAMAccountName field missing for sid %s\n", sidstr
));
994 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
997 a_state
= talloc_p(d_state
, struct samr_account_state
);
999 return NT_STATUS_NO_MEMORY
;
1001 a_state
->sam_ctx
= d_state
->sam_ctx
;
1002 a_state
->access_mask
= r
->in
.access_mask
;
1003 a_state
->domain_state
= talloc_reference(a_state
, d_state
);
1004 a_state
->account_dn
= talloc_steal(a_state
, msgs
[0]->dn
);
1005 a_state
->account_sid
= talloc_strdup(a_state
, sidstr
);
1006 a_state
->account_name
= talloc_strdup(a_state
, groupname
);
1007 if (!a_state
->account_name
|| !a_state
->account_sid
) {
1008 return NT_STATUS_NO_MEMORY
;
1011 /* create the policy handle */
1012 g_handle
= dcesrv_handle_new(dce_call
->conn
, SAMR_HANDLE_GROUP
);
1014 return NT_STATUS_NO_MEMORY
;
1017 g_handle
->data
= a_state
;
1018 g_handle
->destroy
= samr_handle_destroy
;
1020 *r
->out
.group_handle
= g_handle
->wire_handle
;
1022 return NT_STATUS_OK
;
1025 /* these query macros make samr_Query[User|Group]Info a bit easier to read */
1027 #define QUERY_STRING(msg, field, attr) \
1028 r->out.info->field = samdb_result_string(msg, attr, "");
1029 #define QUERY_UINT(msg, field, attr) \
1030 r->out.info->field = samdb_result_uint(msg, attr, 0);
1031 #define QUERY_RID(msg, field, attr) \
1032 r->out.info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
1033 #define QUERY_NTTIME(msg, field, attr) \
1034 r->out.info->field = samdb_result_nttime(msg, attr, 0);
1035 #define QUERY_APASSC(msg, field, attr) \
1036 r->out.info->field = samdb_result_allow_password_change(a_state->sam_ctx, mem_ctx, \
1037 a_state->domain_state->domain_dn, msg, attr);
1038 #define QUERY_FPASSC(msg, field, attr) \
1039 r->out.info->field = samdb_result_force_password_change(a_state->sam_ctx, mem_ctx, \
1040 a_state->domain_state->domain_dn, msg, attr);
1041 #define QUERY_LHOURS(msg, field, attr) \
1042 r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
1043 #define QUERY_AFLAGS(msg, field, attr) \
1044 r->out.info->field = samdb_result_acct_flags(msg, attr);
1047 /* these are used to make the Set[User|Group]Info code easier to follow */
1049 #define SET_STRING(mod, field, attr) do { \
1050 if (r->in.info->field == NULL) return NT_STATUS_INVALID_PARAMETER; \
1051 if (samdb_msg_add_string(a_state->sam_ctx, mem_ctx, mod, attr, r->in.info->field) != 0) { \
1052 return NT_STATUS_NO_MEMORY; \
1056 #define SET_UINT(mod, field, attr) do { \
1057 if (samdb_msg_add_uint(a_state->sam_ctx, mem_ctx, mod, attr, r->in.info->field) != 0) { \
1058 return NT_STATUS_NO_MEMORY; \
1062 #define SET_AFLAGS(msg, field, attr) do { \
1063 if (samdb_msg_add_acct_flags(a_state->sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \
1064 return NT_STATUS_NO_MEMORY; \
1068 #define SET_LHOURS(msg, field, attr) do { \
1069 if (samdb_msg_add_logon_hours(a_state->sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
1070 return NT_STATUS_NO_MEMORY; \
1077 static NTSTATUS
samr_QueryGroupInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1078 struct samr_QueryGroupInfo
*r
)
1080 struct dcesrv_handle
*h
;
1081 struct samr_account_state
*a_state
;
1082 struct ldb_message
*msg
, **res
;
1083 const char * const attrs
[4] = { "sAMAccountName", "description",
1084 "numMembers", NULL
};
1089 DCESRV_PULL_HANDLE(h
, r
->in
.group_handle
, SAMR_HANDLE_GROUP
);
1093 /* pull all the group attributes */
1094 ret
= samdb_search(a_state
->sam_ctx
, mem_ctx
, NULL
, &res
, attrs
,
1095 "dn=%s", a_state
->account_dn
);
1097 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1101 /* allocate the info structure */
1102 r
->out
.info
= talloc_p(mem_ctx
, union samr_GroupInfo
);
1103 if (r
->out
.info
== NULL
) {
1104 return NT_STATUS_NO_MEMORY
;
1106 ZERO_STRUCTP(r
->out
.info
);
1108 /* Fill in the level */
1109 switch (r
->in
.level
) {
1111 QUERY_STRING(msg
, all
.name
.string
, "sAMAccountName");
1112 r
->out
.info
->all
.attributes
= 7; /* Do like w2k3 */
1113 QUERY_UINT (msg
, all
.num_members
, "numMembers")
1114 QUERY_STRING(msg
, all
.description
.string
, "description");
1117 QUERY_STRING(msg
, name
.string
, "sAMAccountName");
1120 r
->out
.info
->unknown
.unknown
= 7;
1122 case GroupInfoDescription
:
1123 QUERY_STRING(msg
, description
.string
, "description");
1127 return NT_STATUS_INVALID_INFO_CLASS
;
1130 return NT_STATUS_OK
;
1137 static NTSTATUS
samr_SetGroupInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1138 struct samr_SetGroupInfo
*r
)
1140 struct dcesrv_handle
*h
;
1141 struct samr_account_state
*a_state
;
1142 struct ldb_message mod
, *msg
= &mod
;
1145 DCESRV_PULL_HANDLE(h
, r
->in
.group_handle
, SAMR_HANDLE_GROUP
);
1150 mod
.dn
= talloc_strdup(mem_ctx
, a_state
->account_dn
);
1152 return NT_STATUS_NO_MEMORY
;
1155 switch (r
->in
.level
) {
1156 case GroupInfoDescription
:
1157 SET_STRING(msg
, description
.string
, "description");
1160 /* On W2k3 this does not change the name, it changes the
1161 * sAMAccountName attribute */
1162 SET_STRING(msg
, name
.string
, "sAMAccountName");
1165 /* This does not do anything obviously visible in W2k3 LDAP */
1168 return NT_STATUS_INVALID_INFO_CLASS
;
1171 /* modify the samdb record */
1172 ret
= samdb_replace(a_state
->sam_ctx
, mem_ctx
, &mod
);
1174 /* we really need samdb.c to return NTSTATUS */
1175 return NT_STATUS_UNSUCCESSFUL
;
1178 return NT_STATUS_OK
;
1185 static NTSTATUS
samr_AddGroupMember(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1186 struct samr_AddGroupMember
*r
)
1188 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1193 samr_DeleteDomainGroup
1195 static NTSTATUS
samr_DeleteDomainGroup(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1196 struct samr_DeleteDomainGroup
*r
)
1198 struct dcesrv_handle
*h
;
1199 struct samr_account_state
*a_state
;
1202 *r
->out
.group_handle
= *r
->in
.group_handle
;
1204 DCESRV_PULL_HANDLE(h
, r
->in
.group_handle
, SAMR_HANDLE_GROUP
);
1208 ret
= samdb_delete(a_state
->sam_ctx
, mem_ctx
, a_state
->account_dn
);
1210 return NT_STATUS_UNSUCCESSFUL
;
1213 ZERO_STRUCTP(r
->out
.group_handle
);
1215 return NT_STATUS_OK
;
1220 samr_DeleteGroupMember
1222 static NTSTATUS
samr_DeleteGroupMember(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1223 struct samr_DeleteGroupMember
*r
)
1225 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1230 samr_QueryGroupMember
1232 static NTSTATUS
samr_QueryGroupMember(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1233 struct samr_QueryGroupMember
*r
)
1235 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1240 samr_SetMemberAttributesOfGroup
1242 static NTSTATUS
samr_SetMemberAttributesOfGroup(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1243 struct samr_SetMemberAttributesOfGroup
*r
)
1245 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1252 static NTSTATUS
samr_OpenAlias(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1253 struct samr_OpenAlias
*r
)
1255 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1262 static NTSTATUS
samr_QueryAliasInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1263 struct samr_QueryAliasInfo
*r
)
1265 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1272 static NTSTATUS
samr_SetAliasInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1273 struct samr_SetAliasInfo
*r
)
1275 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1282 static NTSTATUS
samr_DeleteDomAlias(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1283 struct samr_DeleteDomAlias
*r
)
1285 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1292 static NTSTATUS
samr_AddAliasMember(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1293 struct samr_AddAliasMember
*r
)
1295 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1300 samr_DeleteAliasMember
1302 static NTSTATUS
samr_DeleteAliasMember(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1303 struct samr_DeleteAliasMember
*r
)
1305 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1310 samr_GetMembersInAlias
1312 static NTSTATUS
samr_GetMembersInAlias(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1313 struct samr_GetMembersInAlias
*r
)
1315 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1322 static NTSTATUS
samr_OpenUser(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1323 struct samr_OpenUser
*r
)
1325 struct samr_domain_state
*d_state
;
1326 struct samr_account_state
*a_state
;
1327 struct dcesrv_handle
*h
;
1328 const char *account_name
, *sidstr
;
1329 struct ldb_message
**msgs
;
1330 struct dcesrv_handle
*u_handle
;
1331 const char * const attrs
[2] = { "sAMAccountName", NULL
};
1334 ZERO_STRUCTP(r
->out
.user_handle
);
1336 DCESRV_PULL_HANDLE(h
, r
->in
.domain_handle
, SAMR_HANDLE_DOMAIN
);
1340 /* form the users SID */
1341 sidstr
= talloc_asprintf(mem_ctx
, "%s-%u", d_state
->domain_sid
, r
->in
.rid
);
1343 return NT_STATUS_NO_MEMORY
;
1346 /* search for the user record */
1347 ret
= samdb_search(d_state
->sam_ctx
,
1348 mem_ctx
, d_state
->domain_dn
, &msgs
, attrs
,
1349 "(&(objectSid=%s)(objectclass=user))",
1352 return NT_STATUS_NO_SUCH_USER
;
1355 DEBUG(0,("Found %d records matching sid %s\n", ret
, sidstr
));
1356 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1359 account_name
= samdb_result_string(msgs
[0], "sAMAccountName", NULL
);
1360 if (account_name
== NULL
) {
1361 DEBUG(0,("sAMAccountName field missing for sid %s\n", sidstr
));
1362 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1365 a_state
= talloc_p(d_state
, struct samr_account_state
);
1367 return NT_STATUS_NO_MEMORY
;
1369 a_state
->sam_ctx
= d_state
->sam_ctx
;
1370 a_state
->access_mask
= r
->in
.access_mask
;
1371 a_state
->domain_state
= talloc_reference(a_state
, d_state
);
1372 a_state
->account_dn
= talloc_steal(d_state
, msgs
[0]->dn
);
1373 a_state
->account_sid
= talloc_strdup(d_state
, sidstr
);
1374 a_state
->account_name
= talloc_strdup(d_state
, account_name
);
1375 if (!a_state
->account_name
|| !a_state
->account_sid
) {
1376 return NT_STATUS_NO_MEMORY
;
1379 /* create the policy handle */
1380 u_handle
= dcesrv_handle_new(dce_call
->conn
, SAMR_HANDLE_USER
);
1382 return NT_STATUS_NO_MEMORY
;
1385 u_handle
->data
= a_state
;
1386 u_handle
->destroy
= samr_handle_destroy
;
1388 *r
->out
.user_handle
= u_handle
->wire_handle
;
1390 return NT_STATUS_OK
;
1398 static NTSTATUS
samr_DeleteUser(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1399 struct samr_DeleteUser
*r
)
1401 struct dcesrv_handle
*h
;
1402 struct samr_account_state
*a_state
;
1405 *r
->out
.user_handle
= *r
->in
.user_handle
;
1407 DCESRV_PULL_HANDLE(h
, r
->in
.user_handle
, SAMR_HANDLE_USER
);
1411 ret
= samdb_delete(a_state
->sam_ctx
, mem_ctx
, a_state
->account_dn
);
1413 return NT_STATUS_UNSUCCESSFUL
;
1416 ZERO_STRUCTP(r
->out
.user_handle
);
1418 return NT_STATUS_OK
;
1425 static NTSTATUS
samr_QueryUserInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1426 struct samr_QueryUserInfo
*r
)
1428 struct dcesrv_handle
*h
;
1429 struct samr_account_state
*a_state
;
1430 struct ldb_message
*msg
, **res
;
1435 DCESRV_PULL_HANDLE(h
, r
->in
.user_handle
, SAMR_HANDLE_USER
);
1439 /* pull all the user attributes */
1440 ret
= samdb_search(a_state
->sam_ctx
, mem_ctx
, NULL
, &res
, NULL
,
1441 "dn=%s", a_state
->account_dn
);
1443 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1447 /* allocate the info structure */
1448 r
->out
.info
= talloc_p(mem_ctx
, union samr_UserInfo
);
1449 if (r
->out
.info
== NULL
) {
1450 return NT_STATUS_NO_MEMORY
;
1452 ZERO_STRUCTP(r
->out
.info
);
1454 /* fill in the reply */
1455 switch (r
->in
.level
) {
1457 QUERY_STRING(msg
, info1
.account_name
.string
, "sAMAccountName");
1458 QUERY_STRING(msg
, info1
.full_name
.string
, "displayName");
1459 QUERY_UINT (msg
, info1
.primary_gid
, "primaryGroupID");
1460 QUERY_STRING(msg
, info1
.description
.string
, "description");
1461 QUERY_STRING(msg
, info1
.comment
.string
, "comment");
1465 QUERY_STRING(msg
, info2
.comment
.string
, "comment");
1466 QUERY_UINT (msg
, info2
.country_code
, "countryCode");
1467 QUERY_UINT (msg
, info2
.code_page
, "codePage");
1471 QUERY_STRING(msg
, info3
.account_name
.string
, "sAMAccountName");
1472 QUERY_STRING(msg
, info3
.full_name
.string
, "displayName");
1473 QUERY_RID (msg
, info3
.rid
, "objectSid");
1474 QUERY_UINT (msg
, info3
.primary_gid
, "primaryGroupID");
1475 QUERY_STRING(msg
, info3
.home_directory
.string
, "homeDirectory");
1476 QUERY_STRING(msg
, info3
.home_drive
.string
, "homeDrive");
1477 QUERY_STRING(msg
, info3
.logon_script
.string
, "scriptPath");
1478 QUERY_STRING(msg
, info3
.profile_path
.string
, "profilePath");
1479 QUERY_STRING(msg
, info3
.workstations
.string
, "userWorkstations");
1480 QUERY_NTTIME(msg
, info3
.last_logon
, "lastLogon");
1481 QUERY_NTTIME(msg
, info3
.last_logoff
, "lastLogoff");
1482 QUERY_NTTIME(msg
, info3
.last_password_change
, "pwdLastSet");
1483 QUERY_APASSC(msg
, info3
.allow_password_change
, "pwdLastSet");
1484 QUERY_FPASSC(msg
, info3
.force_password_change
, "pwdLastSet");
1485 QUERY_LHOURS(msg
, info3
.logon_hours
, "logonHours");
1486 QUERY_UINT (msg
, info3
.bad_password_count
, "badPwdCount");
1487 QUERY_UINT (msg
, info3
.logon_count
, "logonCount");
1488 QUERY_AFLAGS(msg
, info3
.acct_flags
, "userAccountControl");
1492 QUERY_LHOURS(msg
, info4
.logon_hours
, "logonHours");
1496 QUERY_STRING(msg
, info5
.account_name
.string
, "sAMAccountName");
1497 QUERY_STRING(msg
, info5
.full_name
.string
, "displayName");
1498 QUERY_RID (msg
, info5
.rid
, "objectSid");
1499 QUERY_UINT (msg
, info5
.primary_gid
, "primaryGroupID");
1500 QUERY_STRING(msg
, info5
.home_directory
.string
, "homeDirectory");
1501 QUERY_STRING(msg
, info5
.home_drive
.string
, "homeDrive");
1502 QUERY_STRING(msg
, info5
.logon_script
.string
, "scriptPath");
1503 QUERY_STRING(msg
, info5
.profile_path
.string
, "profilePath");
1504 QUERY_STRING(msg
, info5
.description
.string
, "description");
1505 QUERY_STRING(msg
, info5
.workstations
.string
, "userWorkstations");
1506 QUERY_NTTIME(msg
, info5
.last_logon
, "lastLogon");
1507 QUERY_NTTIME(msg
, info5
.last_logoff
, "lastLogoff");
1508 QUERY_LHOURS(msg
, info5
.logon_hours
, "logonHours");
1509 QUERY_UINT (msg
, info5
.bad_password_count
, "badPwdCount");
1510 QUERY_UINT (msg
, info5
.logon_count
, "logonCount");
1511 QUERY_NTTIME(msg
, info5
.last_password_change
, "pwdLastSet");
1512 QUERY_NTTIME(msg
, info5
.acct_expiry
, "accountExpires");
1513 QUERY_AFLAGS(msg
, info5
.acct_flags
, "userAccountControl");
1517 QUERY_STRING(msg
, info6
.account_name
.string
, "sAMAccountName");
1518 QUERY_STRING(msg
, info6
.full_name
.string
, "displayName");
1522 QUERY_STRING(msg
, info7
.account_name
.string
, "sAMAccountName");
1526 QUERY_STRING(msg
, info8
.full_name
.string
, "displayName");
1530 QUERY_UINT (msg
, info9
.primary_gid
, "primaryGroupID");
1534 QUERY_STRING(msg
, info10
.home_directory
.string
,"homeDirectory");
1535 QUERY_STRING(msg
, info10
.home_drive
.string
, "homeDrive");
1539 QUERY_STRING(msg
, info11
.logon_script
.string
, "scriptPath");
1543 QUERY_STRING(msg
, info12
.profile_path
.string
, "profilePath");
1547 QUERY_STRING(msg
, info13
.description
.string
, "description");
1551 QUERY_STRING(msg
, info14
.workstations
.string
, "userWorkstations");
1555 QUERY_AFLAGS(msg
, info16
.acct_flags
, "userAccountControl");
1559 QUERY_NTTIME(msg
, info17
.acct_expiry
, "accountExpires");
1562 QUERY_STRING(msg
, info20
.parameters
.string
, "userParameters");
1566 QUERY_NTTIME(msg
, info21
.last_logon
, "lastLogon");
1567 QUERY_NTTIME(msg
, info21
.last_logoff
, "lastLogoff");
1568 QUERY_NTTIME(msg
, info21
.last_password_change
, "pwdLastSet");
1569 QUERY_NTTIME(msg
, info21
.acct_expiry
, "accountExpires");
1570 QUERY_APASSC(msg
, info21
.allow_password_change
,"pwdLastSet");
1571 QUERY_FPASSC(msg
, info21
.force_password_change
,"pwdLastSet");
1572 QUERY_STRING(msg
, info21
.account_name
.string
, "sAMAccountName");
1573 QUERY_STRING(msg
, info21
.full_name
.string
, "displayName");
1574 QUERY_STRING(msg
, info21
.home_directory
.string
,"homeDirectory");
1575 QUERY_STRING(msg
, info21
.home_drive
.string
, "homeDrive");
1576 QUERY_STRING(msg
, info21
.logon_script
.string
, "scriptPath");
1577 QUERY_STRING(msg
, info21
.profile_path
.string
, "profilePath");
1578 QUERY_STRING(msg
, info21
.description
.string
, "description");
1579 QUERY_STRING(msg
, info21
.workstations
.string
, "userWorkstations");
1580 QUERY_STRING(msg
, info21
.comment
.string
, "comment");
1581 QUERY_STRING(msg
, info21
.parameters
.string
, "userParameters");
1582 QUERY_RID (msg
, info21
.rid
, "objectSid");
1583 QUERY_UINT (msg
, info21
.primary_gid
, "primaryGroupID");
1584 QUERY_AFLAGS(msg
, info21
.acct_flags
, "userAccountControl");
1585 r
->out
.info
->info21
.fields_present
= 0x00FFFFFF;
1586 QUERY_LHOURS(msg
, info21
.logon_hours
, "logonHours");
1587 QUERY_UINT (msg
, info21
.bad_password_count
, "badPwdCount");
1588 QUERY_UINT (msg
, info21
.logon_count
, "logonCount");
1589 QUERY_UINT (msg
, info21
.country_code
, "countryCode");
1590 QUERY_UINT (msg
, info21
.code_page
, "codePage");
1596 return NT_STATUS_INVALID_INFO_CLASS
;
1599 return NT_STATUS_OK
;
1606 static NTSTATUS
samr_SetUserInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1607 struct samr_SetUserInfo
*r
)
1609 struct dcesrv_handle
*h
;
1610 struct samr_account_state
*a_state
;
1611 struct ldb_message mod
, *msg
= &mod
;
1613 NTSTATUS status
= NT_STATUS_OK
;
1615 DCESRV_PULL_HANDLE(h
, r
->in
.user_handle
, SAMR_HANDLE_USER
);
1620 mod
.dn
= talloc_strdup(mem_ctx
, a_state
->account_dn
);
1622 return NT_STATUS_NO_MEMORY
;
1625 switch (r
->in
.level
) {
1627 SET_STRING(msg
, info2
.comment
.string
, "comment");
1628 SET_UINT (msg
, info2
.country_code
, "countryCode");
1629 SET_UINT (msg
, info2
.code_page
, "codePage");
1633 SET_LHOURS(msg
, info4
.logon_hours
, "logonHours");
1637 SET_STRING(msg
, info6
.full_name
.string
, "displayName");
1641 SET_STRING(msg
, info8
.full_name
.string
, "displayName");
1645 SET_UINT(msg
, info9
.primary_gid
, "primaryGroupID");
1649 SET_STRING(msg
, info10
.home_directory
.string
, "homeDirectory");
1650 SET_STRING(msg
, info10
.home_drive
.string
, "homeDrive");
1654 SET_STRING(msg
, info11
.logon_script
.string
, "scriptPath");
1658 SET_STRING(msg
, info12
.profile_path
.string
, "profilePath");
1662 SET_STRING(msg
, info13
.description
.string
, "description");
1666 SET_STRING(msg
, info14
.workstations
.string
, "userWorkstations");
1670 SET_AFLAGS(msg
, info16
.acct_flags
, "userAccountControl");
1674 SET_STRING(msg
, info20
.parameters
.string
, "userParameters");
1678 #define IFSET(bit) if (bit & r->in.info->info21.fields_present)
1679 IFSET(SAMR_FIELD_NAME
)
1680 SET_STRING(msg
, info21
.full_name
.string
, "displayName");
1681 IFSET(SAMR_FIELD_DESCRIPTION
)
1682 SET_STRING(msg
, info21
.description
.string
, "description");
1683 IFSET(SAMR_FIELD_COMMENT
)
1684 SET_STRING(msg
, info21
.comment
.string
, "comment");
1685 IFSET(SAMR_FIELD_LOGON_SCRIPT
)
1686 SET_STRING(msg
, info21
.logon_script
.string
, "scriptPath");
1687 IFSET(SAMR_FIELD_PROFILE_PATH
)
1688 SET_STRING(msg
, info21
.profile_path
.string
, "profilePath");
1689 IFSET(SAMR_FIELD_WORKSTATION
)
1690 SET_STRING(msg
, info21
.workstations
.string
, "userWorkstations");
1691 IFSET(SAMR_FIELD_LOGON_HOURS
)
1692 SET_LHOURS(msg
, info21
.logon_hours
, "logonHours");
1693 IFSET(SAMR_FIELD_ACCT_FLAGS
)
1694 SET_AFLAGS(msg
, info21
.acct_flags
, "userAccountControl");
1695 IFSET(SAMR_FIELD_PARAMETERS
)
1696 SET_STRING(msg
, info21
.parameters
.string
, "userParameters");
1697 IFSET(SAMR_FIELD_COUNTRY_CODE
)
1698 SET_UINT (msg
, info21
.country_code
, "countryCode");
1699 IFSET(SAMR_FIELD_CODE_PAGE
)
1700 SET_UINT (msg
, info21
.code_page
, "codePage");
1703 /* Any reason the rest of these can't be set? */
1708 #define IFSET(bit) if (bit & r->in.info->info23.info.fields_present)
1709 IFSET(SAMR_FIELD_NAME
)
1710 SET_STRING(msg
, info23
.info
.full_name
.string
, "displayName");
1711 IFSET(SAMR_FIELD_DESCRIPTION
)
1712 SET_STRING(msg
, info23
.info
.description
.string
, "description");
1713 IFSET(SAMR_FIELD_COMMENT
)
1714 SET_STRING(msg
, info23
.info
.comment
.string
, "comment");
1715 IFSET(SAMR_FIELD_LOGON_SCRIPT
)
1716 SET_STRING(msg
, info23
.info
.logon_script
.string
, "scriptPath");
1717 IFSET(SAMR_FIELD_PROFILE_PATH
)
1718 SET_STRING(msg
, info23
.info
.profile_path
.string
, "profilePath");
1719 IFSET(SAMR_FIELD_WORKSTATION
)
1720 SET_STRING(msg
, info23
.info
.workstations
.string
, "userWorkstations");
1721 IFSET(SAMR_FIELD_LOGON_HOURS
)
1722 SET_LHOURS(msg
, info23
.info
.logon_hours
, "logonHours");
1723 IFSET(SAMR_FIELD_ACCT_FLAGS
)
1724 SET_AFLAGS(msg
, info23
.info
.acct_flags
, "userAccountControl");
1725 IFSET(SAMR_FIELD_PARAMETERS
)
1726 SET_STRING(msg
, info23
.info
.parameters
.string
, "userParameters");
1727 IFSET(SAMR_FIELD_COUNTRY_CODE
)
1728 SET_UINT (msg
, info23
.info
.country_code
, "countryCode");
1729 IFSET(SAMR_FIELD_CODE_PAGE
)
1730 SET_UINT (msg
, info23
.info
.code_page
, "codePage");
1731 IFSET(SAMR_FIELD_PASSWORD
) {
1732 status
= samr_set_password(dce_call
,
1734 a_state
->account_dn
,
1735 a_state
->domain_state
->domain_dn
,
1737 &r
->in
.info
->info23
.password
);
1738 } else IFSET(SAMR_FIELD_PASSWORD2
) {
1739 status
= samr_set_password(dce_call
,
1741 a_state
->account_dn
,
1742 a_state
->domain_state
->domain_dn
,
1744 &r
->in
.info
->info23
.password
);
1749 /* the set password levels are handled separately */
1751 status
= samr_set_password(dce_call
,
1753 a_state
->account_dn
,
1754 a_state
->domain_state
->domain_dn
,
1756 &r
->in
.info
->info24
.password
);
1760 #define IFSET(bit) if (bit & r->in.info->info25.info.fields_present)
1761 IFSET(SAMR_FIELD_NAME
)
1762 SET_STRING(msg
, info25
.info
.full_name
.string
, "displayName");
1763 IFSET(SAMR_FIELD_DESCRIPTION
)
1764 SET_STRING(msg
, info25
.info
.description
.string
, "description");
1765 IFSET(SAMR_FIELD_COMMENT
)
1766 SET_STRING(msg
, info25
.info
.comment
.string
, "comment");
1767 IFSET(SAMR_FIELD_LOGON_SCRIPT
)
1768 SET_STRING(msg
, info25
.info
.logon_script
.string
, "scriptPath");
1769 IFSET(SAMR_FIELD_PROFILE_PATH
)
1770 SET_STRING(msg
, info25
.info
.profile_path
.string
, "profilePath");
1771 IFSET(SAMR_FIELD_WORKSTATION
)
1772 SET_STRING(msg
, info25
.info
.workstations
.string
, "userWorkstations");
1773 IFSET(SAMR_FIELD_LOGON_HOURS
)
1774 SET_LHOURS(msg
, info25
.info
.logon_hours
, "logonHours");
1775 IFSET(SAMR_FIELD_ACCT_FLAGS
)
1776 SET_AFLAGS(msg
, info25
.info
.acct_flags
, "userAccountControl");
1777 IFSET(SAMR_FIELD_PARAMETERS
)
1778 SET_STRING(msg
, info25
.info
.parameters
.string
, "userParameters");
1779 IFSET(SAMR_FIELD_COUNTRY_CODE
)
1780 SET_UINT (msg
, info25
.info
.country_code
, "countryCode");
1781 IFSET(SAMR_FIELD_CODE_PAGE
)
1782 SET_UINT (msg
, info25
.info
.code_page
, "codePage");
1783 IFSET(SAMR_FIELD_PASSWORD
) {
1784 status
= samr_set_password_ex(dce_call
,
1786 a_state
->account_dn
,
1787 a_state
->domain_state
->domain_dn
,
1789 &r
->in
.info
->info25
.password
);
1790 } else IFSET(SAMR_FIELD_PASSWORD2
) {
1791 status
= samr_set_password_ex(dce_call
,
1793 a_state
->account_dn
,
1794 a_state
->domain_state
->domain_dn
,
1796 &r
->in
.info
->info25
.password
);
1801 /* the set password levels are handled separately */
1803 status
= samr_set_password_ex(dce_call
,
1805 a_state
->account_dn
,
1806 a_state
->domain_state
->domain_dn
,
1808 &r
->in
.info
->info26
.password
);
1813 /* many info classes are not valid for SetUserInfo */
1814 return NT_STATUS_INVALID_INFO_CLASS
;
1817 if (!NT_STATUS_IS_OK(status
)) {
1821 /* modify the samdb record */
1822 ret
= samdb_replace(a_state
->sam_ctx
, mem_ctx
, msg
);
1824 /* we really need samdb.c to return NTSTATUS */
1825 return NT_STATUS_UNSUCCESSFUL
;
1828 return NT_STATUS_OK
;
1833 samr_GetGroupsForUser
1835 static NTSTATUS
samr_GetGroupsForUser(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1836 struct samr_GetGroupsForUser
*r
)
1838 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1843 samr_QueryDisplayInfo
1845 static NTSTATUS
samr_QueryDisplayInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1846 struct samr_QueryDisplayInfo
*r
)
1848 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1853 samr_GetDisplayEnumerationIndex
1855 static NTSTATUS
samr_GetDisplayEnumerationIndex(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1856 struct samr_GetDisplayEnumerationIndex
*r
)
1858 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1863 samr_TestPrivateFunctionsDomain
1865 static NTSTATUS
samr_TestPrivateFunctionsDomain(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1866 struct samr_TestPrivateFunctionsDomain
*r
)
1868 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1873 samr_TestPrivateFunctionsUser
1875 static NTSTATUS
samr_TestPrivateFunctionsUser(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1876 struct samr_TestPrivateFunctionsUser
*r
)
1878 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1885 static NTSTATUS
samr_GetUserPwInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1886 struct samr_GetUserPwInfo
*r
)
1888 struct dcesrv_handle
*h
;
1889 struct samr_account_state
*a_state
;
1891 ZERO_STRUCT(r
->out
.info
);
1893 DCESRV_PULL_HANDLE(h
, r
->in
.user_handle
, SAMR_HANDLE_USER
);
1897 r
->out
.info
.min_password_length
= samdb_search_uint(a_state
->sam_ctx
, mem_ctx
, 0, NULL
, "minPwdLength",
1898 "dn=%s", a_state
->domain_state
->domain_dn
);
1899 r
->out
.info
.password_properties
= samdb_search_uint(a_state
->sam_ctx
, mem_ctx
, 0, NULL
, "pwdProperties",
1900 "dn=%s", a_state
->account_dn
);
1901 return NT_STATUS_OK
;
1906 samr_RemoveMemberFromForeignDomain
1908 static NTSTATUS
samr_RemoveMemberFromForeignDomain(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1909 struct samr_RemoveMemberFromForeignDomain
*r
)
1911 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1916 samr_QueryDomainInfo2
1918 static NTSTATUS
samr_QueryDomainInfo2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1919 struct samr_QueryDomainInfo2
*r
)
1921 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1928 just an alias for samr_QueryUserInfo
1930 static NTSTATUS
samr_QueryUserInfo2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1931 struct samr_QueryUserInfo2
*r
)
1933 struct samr_QueryUserInfo r1
;
1936 r1
.in
.user_handle
= r
->in
.user_handle
;
1937 r1
.in
.level
= r
->in
.level
;
1939 status
= samr_QueryUserInfo(dce_call
, mem_ctx
, &r1
);
1941 r
->out
.info
= r1
.out
.info
;
1948 samr_QueryDisplayInfo2
1950 static NTSTATUS
samr_QueryDisplayInfo2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1951 struct samr_QueryDisplayInfo2
*r
)
1953 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1958 samr_GetDisplayEnumerationIndex2
1960 static NTSTATUS
samr_GetDisplayEnumerationIndex2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1961 struct samr_GetDisplayEnumerationIndex2
*r
)
1963 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1968 samr_QueryDisplayInfo3
1970 static NTSTATUS
samr_QueryDisplayInfo3(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1971 struct samr_QueryDisplayInfo3
*r
)
1973 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1978 samr_AddMultipleMembersToAlias
1980 static NTSTATUS
samr_AddMultipleMembersToAlias(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1981 struct samr_AddMultipleMembersToAlias
*r
)
1983 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
1988 samr_RemoveMultipleMembersFromAlias
1990 static NTSTATUS
samr_RemoveMultipleMembersFromAlias(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1991 struct samr_RemoveMultipleMembersFromAlias
*r
)
1993 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2000 this fetches the default password properties for a domain
2002 note that w2k3 completely ignores the domain name in this call, and
2003 always returns the information for the servers primary domain
2005 static NTSTATUS
samr_GetDomPwInfo(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2006 struct samr_GetDomPwInfo
*r
)
2008 struct ldb_message
**msgs
;
2010 const char * const attrs
[] = {"minPwdLength", "pwdProperties", NULL
};
2013 ZERO_STRUCT(r
->out
.info
);
2015 sam_ctx
= samdb_connect(mem_ctx
);
2016 if (sam_ctx
== NULL
) {
2017 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
2020 ret
= samdb_search(sam_ctx
,
2021 mem_ctx
, NULL
, &msgs
, attrs
,
2022 "(&(name=%s)(objectclass=domain))",
2025 return NT_STATUS_NO_SUCH_DOMAIN
;
2028 samdb_search_free(sam_ctx
, mem_ctx
, msgs
);
2029 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2032 r
->out
.info
.min_password_length
= samdb_result_uint(msgs
[0], "minPwdLength", 0);
2033 r
->out
.info
.password_properties
= samdb_result_uint(msgs
[0], "pwdProperties", 1);
2035 samdb_search_free(sam_ctx
, mem_ctx
, msgs
);
2037 talloc_free(sam_ctx
);
2038 return NT_STATUS_OK
;
2045 static NTSTATUS
samr_Connect2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2046 struct samr_Connect2
*r
)
2048 struct samr_Connect c
;
2050 c
.in
.system_name
= NULL
;
2051 c
.in
.access_mask
= r
->in
.access_mask
;
2052 c
.out
.connect_handle
= r
->out
.connect_handle
;
2054 return samr_Connect(dce_call
, mem_ctx
, &c
);
2061 just an alias for samr_SetUserInfo
2063 static NTSTATUS
samr_SetUserInfo2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2064 struct samr_SetUserInfo2
*r
)
2066 struct samr_SetUserInfo r2
;
2068 r2
.in
.user_handle
= r
->in
.user_handle
;
2069 r2
.in
.level
= r
->in
.level
;
2070 r2
.in
.info
= r
->in
.info
;
2072 return samr_SetUserInfo(dce_call
, mem_ctx
, &r2
);
2077 samr_SetBootKeyInformation
2079 static NTSTATUS
samr_SetBootKeyInformation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2080 struct samr_SetBootKeyInformation
*r
)
2082 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2087 samr_GetBootKeyInformation
2089 static NTSTATUS
samr_GetBootKeyInformation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2090 struct samr_GetBootKeyInformation
*r
)
2092 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2099 static NTSTATUS
samr_Connect3(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2100 struct samr_Connect3
*r
)
2102 struct samr_Connect c
;
2104 c
.in
.system_name
= NULL
;
2105 c
.in
.access_mask
= r
->in
.access_mask
;
2106 c
.out
.connect_handle
= r
->out
.connect_handle
;
2108 return samr_Connect(dce_call
, mem_ctx
, &c
);
2115 static NTSTATUS
samr_Connect4(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2116 struct samr_Connect4
*r
)
2118 struct samr_Connect c
;
2120 c
.in
.system_name
= NULL
;
2121 c
.in
.access_mask
= r
->in
.access_mask
;
2122 c
.out
.connect_handle
= r
->out
.connect_handle
;
2124 return samr_Connect(dce_call
, mem_ctx
, &c
);
2131 static NTSTATUS
samr_Connect5(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2132 struct samr_Connect5
*r
)
2134 struct samr_Connect c
;
2137 c
.in
.system_name
= NULL
;
2138 c
.in
.access_mask
= r
->in
.access_mask
;
2139 c
.out
.connect_handle
= r
->out
.connect_handle
;
2141 status
= samr_Connect(dce_call
, mem_ctx
, &c
);
2143 r
->out
.info
->info1
.unknown1
= 3;
2144 r
->out
.info
->info1
.unknown2
= 0;
2145 r
->out
.level
= r
->in
.level
;
2154 static NTSTATUS
samr_RidToSid(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2155 struct samr_RidToSid
*r
)
2157 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2162 samr_SetDsrmPassword
2164 static NTSTATUS
samr_SetDsrmPassword(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2165 struct samr_SetDsrmPassword
*r
)
2167 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2172 samr_ValidatePassword
2174 static NTSTATUS
samr_ValidatePassword(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
2175 struct samr_ValidatePassword
*r
)
2177 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
2181 /* include the generated boilerplate */
2182 #include "librpc/gen_ndr/ndr_samr_s.c"