2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Gerald (Jerry) Carter 2006.
7 * Copyright (C) Guenther Deschner 2007-2008.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 /* This is the implementation of the wks interface. */
26 #include "librpc/gen_ndr/libnet_join.h"
27 #include "libnet/libnet_join.h"
28 #include "../libcli/auth/libcli_auth.h"
29 #include "../librpc/gen_ndr/srv_wkssvc.h"
30 #include "../libcli/security/security.h"
33 #define DBGC_CLASS DBGC_RPC_SRV
47 struct timeval login_time
;
50 static int usr_info_cmp(const struct usrinfo
*usr1
, const struct usrinfo
*usr2
)
52 /* Called from qsort to compare two users in a usrinfo_t array for
53 * sorting by login time. Return >0 if usr1 login time was later than
54 * usr2 login time, <0 if it was earlier */
55 return timeval_compare(&usr1
->login_time
, &usr2
->login_time
);
58 /*******************************************************************
59 Get a list of the names of all users logged into this machine
60 ********************************************************************/
62 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
66 struct usrinfo
*usr_infos
= NULL
;
69 while ((u
= getutxent()) != NULL
) {
71 if (u
->ut_type
!= USER_PROCESS
) {
74 for (i
= 0; i
< num_users
; i
++) {
75 /* getutxent can return multiple user entries for the
76 * same user, so ignore any dups */
77 if (strcmp(u
->ut_user
, usr_infos
[i
].name
) == 0) {
85 tmp
= talloc_realloc(mem_ctx
, usr_infos
, struct usrinfo
,
93 usr_infos
[num_users
].name
= talloc_strdup(usr_infos
,
95 if (usr_infos
[num_users
].name
== NULL
) {
96 TALLOC_FREE(usr_infos
);
100 usr_infos
[num_users
].login_time
.tv_sec
= u
->ut_tv
.tv_sec
;
101 usr_infos
[num_users
].login_time
.tv_usec
= u
->ut_tv
.tv_usec
;
105 /* Sort the user list by time, oldest first */
106 TYPESAFE_QSORT(usr_infos
, num_users
, usr_info_cmp
);
108 users
= (char**)talloc_array(mem_ctx
, char*, num_users
);
110 for (i
= 0; i
< num_users
; i
++) {
111 users
[i
] = talloc_move(users
, &usr_infos
[i
].name
);
114 TALLOC_FREE(usr_infos
);
122 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
129 static int dom_user_cmp(const struct dom_usr
*usr1
, const struct dom_usr
*usr2
)
131 /* Called from qsort to compare two domain users in a dom_usr_t array
132 * for sorting by login time. Return >0 if usr1 login time was later
133 * than usr2 login time, <0 if it was earlier */
134 return (usr1
->login_time
- usr2
->login_time
);
137 /*******************************************************************
138 Get a list of the names of all users of this machine who are
139 logged into the domain.
141 This should return a list of the users on this machine who are
142 logged into the domain (i.e. have been authenticated by the domain's
143 password server) but that doesn't fit well with the normal Samba
144 scenario where accesses out to the domain are made through smbclient
145 with each such session individually authenticated. So about the best
146 we can do currently is to list sessions of local users connected to
147 this server, which means that to get themself included in the list a
148 local user must create a session to the local samba server by running:
149 smbclient \\\\localhost\\share
151 FIXME: find a better way to get local users logged into the domain
153 ********************************************************************/
155 static struct dom_usr
*get_domain_userlist(TALLOC_CTX
*mem_ctx
)
157 struct sessionid
*session_list
= NULL
;
158 char *machine_name
, *p
, *nm
;
160 struct dom_usr
*users
, *tmp
;
161 int i
, num_users
, num_sessions
;
163 sep
= lp_winbind_separator();
168 num_sessions
= list_sessions(mem_ctx
, &session_list
);
169 if (num_sessions
== 0) {
174 users
= talloc_array(mem_ctx
, struct dom_usr
, num_sessions
);
176 TALLOC_FREE(session_list
);
180 for (i
=num_users
=0; i
<num_sessions
; i
++) {
181 if (!session_list
[i
].username
182 || !session_list
[i
].remote_machine
) {
185 p
= strpbrk(session_list
[i
].remote_machine
, "./");
189 machine_name
= talloc_asprintf_strupper_m(
190 users
, "%s", session_list
[i
].remote_machine
);
191 if (machine_name
== NULL
) {
192 DEBUG(10, ("talloc_asprintf failed\n"));
195 if (strcmp(machine_name
, global_myname()) == 0) {
196 p
= session_list
[i
].username
;
200 * "domain+name" format so split domain and
205 users
[num_users
].domain
=
206 talloc_asprintf_strupper_m(users
,
208 users
[num_users
].name
= talloc_strdup(users
,
212 * Simple user name so get domain from smb.conf
214 users
[num_users
].domain
=
215 talloc_strdup(users
, lp_workgroup());
216 users
[num_users
].name
= talloc_strdup(users
,
219 users
[num_users
].login_time
=
220 session_list
[i
].connect_start
;
223 TALLOC_FREE(machine_name
);
225 TALLOC_FREE(session_list
);
227 tmp
= talloc_realloc(mem_ctx
, users
, struct dom_usr
, num_users
);
233 /* Sort the user list by time, oldest first */
234 TYPESAFE_QSORT(users
, num_users
, dom_user_cmp
);
240 /*******************************************************************
241 RPC Workstation Service request NetWkstaGetInfo with level 100.
242 Returns to the requester:
244 - The smb version number
246 Returns a filled in wkssvc_NetWkstaInfo100 struct.
247 ********************************************************************/
249 static struct wkssvc_NetWkstaInfo100
*create_wks_info_100(TALLOC_CTX
*mem_ctx
)
251 struct wkssvc_NetWkstaInfo100
*info100
;
253 info100
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo100
);
254 if (info100
== NULL
) {
258 info100
->platform_id
= PLATFORM_ID_NT
; /* unknown */
259 info100
->version_major
= lp_major_announce_version();
260 info100
->version_minor
= lp_minor_announce_version();
262 info100
->server_name
= talloc_asprintf_strupper_m(
263 info100
, "%s", global_myname());
264 info100
->domain_name
= talloc_asprintf_strupper_m(
265 info100
, "%s", lp_workgroup());
270 /*******************************************************************
271 RPC Workstation Service request NetWkstaGetInfo with level 101.
272 Returns to the requester:
273 - As per NetWkstaGetInfo with level 100, plus:
274 - The LANMAN directory path (not currently supported).
275 Returns a filled in wkssvc_NetWkstaInfo101 struct.
276 ********************************************************************/
278 static struct wkssvc_NetWkstaInfo101
*create_wks_info_101(TALLOC_CTX
*mem_ctx
)
280 struct wkssvc_NetWkstaInfo101
*info101
;
282 info101
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo101
);
283 if (info101
== NULL
) {
287 info101
->platform_id
= PLATFORM_ID_NT
; /* unknown */
288 info101
->version_major
= lp_major_announce_version();
289 info101
->version_minor
= lp_minor_announce_version();
291 info101
->server_name
= talloc_asprintf_strupper_m(
292 info101
, "%s", global_myname());
293 info101
->domain_name
= talloc_asprintf_strupper_m(
294 info101
, "%s", lp_workgroup());
295 info101
->lan_root
= "";
300 /*******************************************************************
301 RPC Workstation Service request NetWkstaGetInfo with level 102.
302 Returns to the requester:
303 - As per NetWkstaGetInfo with level 101, plus:
304 - The number of logged in users.
305 Returns a filled in wkssvc_NetWkstaInfo102 struct.
306 ********************************************************************/
308 static struct wkssvc_NetWkstaInfo102
*create_wks_info_102(TALLOC_CTX
*mem_ctx
)
310 struct wkssvc_NetWkstaInfo102
*info102
;
313 info102
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo102
);
314 if (info102
== NULL
) {
318 info102
->platform_id
= PLATFORM_ID_NT
; /* unknown */
319 info102
->version_major
= lp_major_announce_version();
320 info102
->version_minor
= lp_minor_announce_version();
322 info102
->server_name
= talloc_asprintf_strupper_m(
323 info102
, "%s", global_myname());
324 info102
->domain_name
= talloc_asprintf_strupper_m(
325 info102
, "%s", lp_workgroup());
326 info102
->lan_root
= "";
328 users
= get_logged_on_userlist(talloc_tos());
329 info102
->logged_on_users
= talloc_array_length(users
);
336 /********************************************************************
337 Handling for RPC Workstation Service request NetWkstaGetInfo
338 ********************************************************************/
340 WERROR
_wkssvc_NetWkstaGetInfo(struct pipes_struct
*p
,
341 struct wkssvc_NetWkstaGetInfo
*r
)
343 switch (r
->in
.level
) {
345 /* Level 100 can be allowed from anyone including anonymous
346 * so no access checks are needed for this case */
347 r
->out
.info
->info100
= create_wks_info_100(p
->mem_ctx
);
348 if (r
->out
.info
->info100
== NULL
) {
353 /* Level 101 can be allowed from any logged in user */
354 if (!nt_token_check_sid(&global_sid_Authenticated_Users
,
355 p
->server_info
->ptok
)) {
356 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
358 DEBUGADD(3,(" - does not have sid for Authenticated "
361 &global_sid_Authenticated_Users
)));
362 security_token_debug(DBGC_CLASS
, 3,
363 p
->server_info
->ptok
);
364 return WERR_ACCESS_DENIED
;
366 r
->out
.info
->info101
= create_wks_info_101(p
->mem_ctx
);
367 if (r
->out
.info
->info101
== NULL
) {
372 /* Level 102 Should only be allowed from a domain administrator */
373 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
374 p
->server_info
->ptok
)) {
375 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
377 DEBUGADD(3,(" - does not have sid for Administrators "
378 "group %s, sids are:\n",
379 sid_string_dbg(&global_sid_Builtin_Administrators
)));
380 security_token_debug(DBGC_CLASS
, 3,
381 p
->server_info
->ptok
);
382 return WERR_ACCESS_DENIED
;
384 r
->out
.info
->info102
= create_wks_info_102(p
->mem_ctx
);
385 if (r
->out
.info
->info102
== NULL
) {
390 return WERR_UNKNOWN_LEVEL
;
396 /********************************************************************
397 ********************************************************************/
399 WERROR
_wkssvc_NetWkstaSetInfo(struct pipes_struct
*p
,
400 struct wkssvc_NetWkstaSetInfo
*r
)
402 /* FIXME: Add implementation code here */
403 p
->rng_fault_state
= True
;
404 return WERR_NOT_SUPPORTED
;
407 /********************************************************************
408 RPC Workstation Service request NetWkstaEnumUsers with level 0:
409 Returns to the requester:
410 - the user names of the logged in users.
411 Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct.
412 ********************************************************************/
414 static struct wkssvc_NetWkstaEnumUsersCtr0
*create_enum_users0(
417 struct wkssvc_NetWkstaEnumUsersCtr0
*ctr0
;
421 ctr0
= talloc(mem_ctx
, struct wkssvc_NetWkstaEnumUsersCtr0
);
426 users
= get_logged_on_userlist(talloc_tos());
427 if (users
== NULL
&& errno
!= 0) {
428 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
429 errno
, strerror(errno
)));
434 num_users
= talloc_array_length(users
);
435 ctr0
->entries_read
= num_users
;
436 ctr0
->user0
= talloc_array(ctr0
, struct wkssvc_NetrWkstaUserInfo0
,
438 if (ctr0
->user0
== NULL
) {
444 for (i
=0; i
<num_users
; i
++) {
445 ctr0
->user0
[i
].user_name
= talloc_move(ctr0
->user0
, &users
[i
]);
451 /********************************************************************
452 RPC Workstation Service request NetWkstaEnumUsers with level 1.
453 Returns to the requester:
454 - the user names of the logged in users,
455 - the domain or machine each is logged into,
456 - the password server that was used to authenticate each,
457 - other domains each user is logged into (not currently supported).
458 Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct.
459 ********************************************************************/
461 static struct wkssvc_NetWkstaEnumUsersCtr1
*create_enum_users1(
464 struct wkssvc_NetWkstaEnumUsersCtr1
*ctr1
;
466 struct dom_usr
*dom_users
;
467 const char *pwd_server
;
469 int i
, j
, num_users
, num_dom_users
;
471 ctr1
= talloc(mem_ctx
, struct wkssvc_NetWkstaEnumUsersCtr1
);
476 users
= get_logged_on_userlist(talloc_tos());
477 if (users
== NULL
&& errno
!= 0) {
478 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
479 errno
, strerror(errno
)));
483 num_users
= talloc_array_length(users
);
485 dom_users
= get_domain_userlist(talloc_tos());
486 if (dom_users
== NULL
&& errno
!= 0) {
491 num_dom_users
= talloc_array_length(dom_users
);
493 ctr1
->user1
= talloc_array(ctr1
, struct wkssvc_NetrWkstaUserInfo1
,
494 num_users
+num_dom_users
);
495 if (ctr1
->user1
== NULL
) {
498 TALLOC_FREE(dom_users
);
504 if ((pwd_tmp
= talloc_strdup(ctr1
->user1
, lp_passwordserver()))) {
505 /* The configured password server is a full DNS name but
506 * for the logon server we need to return just the first
507 * component (machine name) of it in upper-case */
508 char *p
= strchr(pwd_tmp
, '.');
512 p
= pwd_tmp
+ strlen(pwd_tmp
);
514 while (--p
>= pwd_tmp
) {
517 pwd_server
= pwd_tmp
;
520 /* Put in local users first */
521 for (i
=0; i
<num_users
; i
++) {
522 ctr1
->user1
[i
].user_name
= talloc_move(ctr1
->user1
, &users
[i
]);
524 /* For a local user the domain name and logon server are
525 * both returned as the local machine's NetBIOS name */
526 ctr1
->user1
[i
].logon_domain
= ctr1
->user1
[i
].logon_server
=
527 talloc_asprintf_strupper_m(ctr1
->user1
, "%s", global_myname());
529 ctr1
->user1
[i
].other_domains
= NULL
; /* Maybe in future? */
532 /* Now domain users */
533 for (j
=0; j
<num_dom_users
; j
++) {
534 ctr1
->user1
[i
].user_name
=
535 talloc_strdup(ctr1
->user1
, dom_users
[j
].name
);
536 ctr1
->user1
[i
].logon_domain
=
537 talloc_strdup(ctr1
->user1
, dom_users
[j
].domain
);
538 ctr1
->user1
[i
].logon_server
= pwd_server
;
540 ctr1
->user1
[i
++].other_domains
= NULL
; /* Maybe in future? */
543 ctr1
->entries_read
= i
;
546 TALLOC_FREE(dom_users
);
550 /********************************************************************
551 Handling for RPC Workstation Service request NetWkstaEnumUsers
552 (a.k.a Windows NetWkstaUserEnum)
553 ********************************************************************/
555 WERROR
_wkssvc_NetWkstaEnumUsers(struct pipes_struct
*p
,
556 struct wkssvc_NetWkstaEnumUsers
*r
)
558 /* This with any level should only be allowed from a domain administrator */
559 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
560 p
->server_info
->ptok
)) {
561 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
562 DEBUGADD(3,(" - does not have sid for Administrators group "
563 "%s\n", sid_string_dbg(
564 &global_sid_Builtin_Administrators
)));
565 security_token_debug(DBGC_CLASS
, 3, p
->server_info
->ptok
);
566 return WERR_ACCESS_DENIED
;
569 switch (r
->in
.info
->level
) {
571 r
->out
.info
->ctr
.user0
= create_enum_users0(p
->mem_ctx
);
572 if (r
->out
.info
->ctr
.user0
== NULL
) {
575 r
->out
.info
->level
= r
->in
.info
->level
;
576 *r
->out
.entries_read
= r
->out
.info
->ctr
.user0
->entries_read
;
577 *r
->out
.resume_handle
= 0;
580 r
->out
.info
->ctr
.user1
= create_enum_users1(p
->mem_ctx
);
581 if (r
->out
.info
->ctr
.user1
== NULL
) {
584 r
->out
.info
->level
= r
->in
.info
->level
;
585 *r
->out
.entries_read
= r
->out
.info
->ctr
.user1
->entries_read
;
586 *r
->out
.resume_handle
= 0;
589 return WERR_UNKNOWN_LEVEL
;
595 /********************************************************************
596 ********************************************************************/
598 WERROR
_wkssvc_NetrWkstaUserGetInfo(struct pipes_struct
*p
,
599 struct wkssvc_NetrWkstaUserGetInfo
*r
)
601 /* FIXME: Add implementation code here */
602 p
->rng_fault_state
= True
;
603 return WERR_NOT_SUPPORTED
;
606 /********************************************************************
607 ********************************************************************/
609 WERROR
_wkssvc_NetrWkstaUserSetInfo(struct pipes_struct
*p
,
610 struct wkssvc_NetrWkstaUserSetInfo
*r
)
612 /* FIXME: Add implementation code here */
613 p
->rng_fault_state
= True
;
614 return WERR_NOT_SUPPORTED
;
617 /********************************************************************
618 ********************************************************************/
620 WERROR
_wkssvc_NetWkstaTransportEnum(struct pipes_struct
*p
,
621 struct wkssvc_NetWkstaTransportEnum
*r
)
623 /* FIXME: Add implementation code here */
624 p
->rng_fault_state
= True
;
625 return WERR_NOT_SUPPORTED
;
628 /********************************************************************
629 ********************************************************************/
631 WERROR
_wkssvc_NetrWkstaTransportAdd(struct pipes_struct
*p
,
632 struct wkssvc_NetrWkstaTransportAdd
*r
)
634 /* FIXME: Add implementation code here */
635 p
->rng_fault_state
= True
;
636 return WERR_NOT_SUPPORTED
;
639 /********************************************************************
640 ********************************************************************/
642 WERROR
_wkssvc_NetrWkstaTransportDel(struct pipes_struct
*p
,
643 struct wkssvc_NetrWkstaTransportDel
*r
)
645 /* FIXME: Add implementation code here */
646 p
->rng_fault_state
= True
;
647 return WERR_NOT_SUPPORTED
;
650 /********************************************************************
651 ********************************************************************/
653 WERROR
_wkssvc_NetrUseAdd(struct pipes_struct
*p
,
654 struct wkssvc_NetrUseAdd
*r
)
656 /* FIXME: Add implementation code here */
657 p
->rng_fault_state
= True
;
658 return WERR_NOT_SUPPORTED
;
661 /********************************************************************
662 ********************************************************************/
664 WERROR
_wkssvc_NetrUseGetInfo(struct pipes_struct
*p
,
665 struct wkssvc_NetrUseGetInfo
*r
)
667 /* FIXME: Add implementation code here */
668 p
->rng_fault_state
= True
;
669 return WERR_NOT_SUPPORTED
;
672 /********************************************************************
673 ********************************************************************/
675 WERROR
_wkssvc_NetrUseDel(struct pipes_struct
*p
,
676 struct wkssvc_NetrUseDel
*r
)
678 /* FIXME: Add implementation code here */
679 p
->rng_fault_state
= True
;
680 return WERR_NOT_SUPPORTED
;
683 /********************************************************************
684 ********************************************************************/
686 WERROR
_wkssvc_NetrUseEnum(struct pipes_struct
*p
,
687 struct wkssvc_NetrUseEnum
*r
)
689 /* FIXME: Add implementation code here */
690 p
->rng_fault_state
= True
;
691 return WERR_NOT_SUPPORTED
;
694 /********************************************************************
695 ********************************************************************/
697 WERROR
_wkssvc_NetrMessageBufferSend(struct pipes_struct
*p
,
698 struct wkssvc_NetrMessageBufferSend
*r
)
700 /* FIXME: Add implementation code here */
701 p
->rng_fault_state
= True
;
702 return WERR_NOT_SUPPORTED
;
705 /********************************************************************
706 ********************************************************************/
708 WERROR
_wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct
*p
,
709 struct wkssvc_NetrWorkstationStatisticsGet
*r
)
711 /* FIXME: Add implementation code here */
712 p
->rng_fault_state
= True
;
713 return WERR_NOT_SUPPORTED
;
716 /********************************************************************
717 ********************************************************************/
719 WERROR
_wkssvc_NetrLogonDomainNameAdd(struct pipes_struct
*p
,
720 struct wkssvc_NetrLogonDomainNameAdd
*r
)
722 /* FIXME: Add implementation code here */
723 p
->rng_fault_state
= True
;
724 return WERR_NOT_SUPPORTED
;
727 /********************************************************************
728 ********************************************************************/
730 WERROR
_wkssvc_NetrLogonDomainNameDel(struct pipes_struct
*p
,
731 struct wkssvc_NetrLogonDomainNameDel
*r
)
733 /* FIXME: Add implementation code here */
734 p
->rng_fault_state
= True
;
735 return WERR_NOT_SUPPORTED
;
738 /********************************************************************
739 ********************************************************************/
741 WERROR
_wkssvc_NetrJoinDomain(struct pipes_struct
*p
,
742 struct wkssvc_NetrJoinDomain
*r
)
744 /* FIXME: Add implementation code here */
745 p
->rng_fault_state
= True
;
746 return WERR_NOT_SUPPORTED
;
749 /********************************************************************
750 ********************************************************************/
752 WERROR
_wkssvc_NetrUnjoinDomain(struct pipes_struct
*p
,
753 struct wkssvc_NetrUnjoinDomain
*r
)
755 /* FIXME: Add implementation code here */
756 p
->rng_fault_state
= True
;
757 return WERR_NOT_SUPPORTED
;
760 /********************************************************************
761 ********************************************************************/
763 WERROR
_wkssvc_NetrRenameMachineInDomain(struct pipes_struct
*p
,
764 struct wkssvc_NetrRenameMachineInDomain
*r
)
766 /* FIXME: Add implementation code here */
767 p
->rng_fault_state
= True
;
768 return WERR_NOT_SUPPORTED
;
771 /********************************************************************
772 ********************************************************************/
774 WERROR
_wkssvc_NetrValidateName(struct pipes_struct
*p
,
775 struct wkssvc_NetrValidateName
*r
)
777 /* FIXME: Add implementation code here */
778 p
->rng_fault_state
= True
;
779 return WERR_NOT_SUPPORTED
;
782 /********************************************************************
783 ********************************************************************/
785 WERROR
_wkssvc_NetrGetJoinInformation(struct pipes_struct
*p
,
786 struct wkssvc_NetrGetJoinInformation
*r
)
788 /* FIXME: Add implementation code here */
789 p
->rng_fault_state
= True
;
790 return WERR_NOT_SUPPORTED
;
793 /********************************************************************
794 ********************************************************************/
796 WERROR
_wkssvc_NetrGetJoinableOus(struct pipes_struct
*p
,
797 struct wkssvc_NetrGetJoinableOus
*r
)
799 /* FIXME: Add implementation code here */
800 p
->rng_fault_state
= True
;
801 return WERR_NOT_SUPPORTED
;
804 /********************************************************************
805 _wkssvc_NetrJoinDomain2
806 ********************************************************************/
808 WERROR
_wkssvc_NetrJoinDomain2(struct pipes_struct
*p
,
809 struct wkssvc_NetrJoinDomain2
*r
)
811 struct libnet_JoinCtx
*j
= NULL
;
812 char *cleartext_pwd
= NULL
;
813 char *admin_domain
= NULL
;
814 char *admin_account
= NULL
;
816 struct security_token
*token
= p
->server_info
->ptok
;
818 if (!r
->in
.domain_name
) {
819 return WERR_INVALID_PARAM
;
822 if (!r
->in
.admin_account
|| !r
->in
.encrypted_password
) {
823 return WERR_INVALID_PARAM
;
826 if (!security_token_has_privilege(token
, SEC_PRIV_MACHINE_ACCOUNT
) &&
827 !nt_token_check_domain_rid(token
, DOMAIN_RID_ADMINS
) &&
828 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
829 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
830 "sufficient privileges\n"));
831 return WERR_ACCESS_DENIED
;
834 if ((r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED
) ||
835 (r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_JOIN_UNSECURE
)) {
836 return WERR_NOT_SUPPORTED
;
839 werr
= decode_wkssvc_join_password_buffer(
840 p
->mem_ctx
, r
->in
.encrypted_password
,
841 &p
->server_info
->user_session_key
, &cleartext_pwd
);
842 if (!W_ERROR_IS_OK(werr
)) {
846 split_domain_user(p
->mem_ctx
,
851 werr
= libnet_init_JoinCtx(p
->mem_ctx
, &j
);
852 if (!W_ERROR_IS_OK(werr
)) {
856 j
->in
.domain_name
= r
->in
.domain_name
;
857 j
->in
.account_ou
= r
->in
.account_ou
;
858 j
->in
.join_flags
= r
->in
.join_flags
;
859 j
->in
.admin_account
= admin_account
;
860 j
->in
.admin_password
= cleartext_pwd
;
862 j
->in
.modify_config
= lp_config_backend_is_registry();
863 j
->in
.msg_ctx
= p
->msg_ctx
;
866 werr
= libnet_Join(p
->mem_ctx
, j
);
869 if (!W_ERROR_IS_OK(werr
)) {
870 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
871 j
->out
.error_string
? j
->out
.error_string
:
879 /********************************************************************
880 _wkssvc_NetrUnjoinDomain2
881 ********************************************************************/
883 WERROR
_wkssvc_NetrUnjoinDomain2(struct pipes_struct
*p
,
884 struct wkssvc_NetrUnjoinDomain2
*r
)
886 struct libnet_UnjoinCtx
*u
= NULL
;
887 char *cleartext_pwd
= NULL
;
888 char *admin_domain
= NULL
;
889 char *admin_account
= NULL
;
891 struct security_token
*token
= p
->server_info
->ptok
;
893 if (!r
->in
.account
|| !r
->in
.encrypted_password
) {
894 return WERR_INVALID_PARAM
;
897 if (!security_token_has_privilege(token
, SEC_PRIV_MACHINE_ACCOUNT
) &&
898 !nt_token_check_domain_rid(token
, DOMAIN_RID_ADMINS
) &&
899 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
900 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
901 "sufficient privileges\n"));
902 return WERR_ACCESS_DENIED
;
905 werr
= decode_wkssvc_join_password_buffer(
906 p
->mem_ctx
, r
->in
.encrypted_password
,
907 &p
->server_info
->user_session_key
, &cleartext_pwd
);
908 if (!W_ERROR_IS_OK(werr
)) {
912 split_domain_user(p
->mem_ctx
,
917 werr
= libnet_init_UnjoinCtx(p
->mem_ctx
, &u
);
918 if (!W_ERROR_IS_OK(werr
)) {
922 u
->in
.domain_name
= lp_realm();
923 u
->in
.unjoin_flags
= r
->in
.unjoin_flags
|
924 WKSSVC_JOIN_FLAGS_JOIN_TYPE
;
925 u
->in
.admin_account
= admin_account
;
926 u
->in
.admin_password
= cleartext_pwd
;
928 u
->in
.modify_config
= lp_config_backend_is_registry();
929 u
->in
.msg_ctx
= p
->msg_ctx
;
932 werr
= libnet_Unjoin(p
->mem_ctx
, u
);
935 if (!W_ERROR_IS_OK(werr
)) {
936 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
937 u
->out
.error_string
? u
->out
.error_string
:
945 /********************************************************************
946 ********************************************************************/
948 WERROR
_wkssvc_NetrRenameMachineInDomain2(struct pipes_struct
*p
,
949 struct wkssvc_NetrRenameMachineInDomain2
*r
)
951 /* for now just return not supported */
952 return WERR_NOT_SUPPORTED
;
955 /********************************************************************
956 ********************************************************************/
958 WERROR
_wkssvc_NetrValidateName2(struct pipes_struct
*p
,
959 struct wkssvc_NetrValidateName2
*r
)
961 /* FIXME: Add implementation code here */
962 p
->rng_fault_state
= True
;
963 return WERR_NOT_SUPPORTED
;
966 /********************************************************************
967 ********************************************************************/
969 WERROR
_wkssvc_NetrGetJoinableOus2(struct pipes_struct
*p
,
970 struct wkssvc_NetrGetJoinableOus2
*r
)
972 /* FIXME: Add implementation code here */
973 p
->rng_fault_state
= True
;
974 return WERR_NOT_SUPPORTED
;
977 /********************************************************************
978 ********************************************************************/
980 WERROR
_wkssvc_NetrAddAlternateComputerName(struct pipes_struct
*p
,
981 struct wkssvc_NetrAddAlternateComputerName
*r
)
983 /* FIXME: Add implementation code here */
984 p
->rng_fault_state
= True
;
985 return WERR_NOT_SUPPORTED
;
988 /********************************************************************
989 ********************************************************************/
991 WERROR
_wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct
*p
,
992 struct wkssvc_NetrRemoveAlternateComputerName
*r
)
994 /* FIXME: Add implementation code here */
995 p
->rng_fault_state
= True
;
996 return WERR_NOT_SUPPORTED
;
999 /********************************************************************
1000 ********************************************************************/
1002 WERROR
_wkssvc_NetrSetPrimaryComputername(struct pipes_struct
*p
,
1003 struct wkssvc_NetrSetPrimaryComputername
*r
)
1005 /* FIXME: Add implementation code here */
1006 p
->rng_fault_state
= True
;
1007 return WERR_NOT_SUPPORTED
;
1010 /********************************************************************
1011 ********************************************************************/
1013 WERROR
_wkssvc_NetrEnumerateComputerNames(struct pipes_struct
*p
,
1014 struct wkssvc_NetrEnumerateComputerNames
*r
)
1016 /* FIXME: Add implementation code here */
1017 p
->rng_fault_state
= True
;
1018 return WERR_NOT_SUPPORTED
;