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 "libnet/libnet.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../librpc/gen_ndr/srv_wkssvc.h"
31 #define DBGC_CLASS DBGC_RPC_SRV
45 struct timeval login_time
;
48 static int usr_info_cmp(const struct usrinfo
*usr1
, const struct usrinfo
*usr2
)
50 /* Called from qsort to compare two users in a usrinfo_t array for
51 * sorting by login time. Return >0 if usr1 login time was later than
52 * usr2 login time, <0 if it was earlier */
53 return timeval_compare(&usr1
->login_time
, &usr2
->login_time
);
56 /*******************************************************************
57 Get a list of the names of all users logged into this machine
58 ********************************************************************/
60 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
64 struct usrinfo
*usr_infos
= NULL
;
67 while ((u
= getutxent()) != NULL
) {
69 if (u
->ut_type
!= USER_PROCESS
) {
72 for (i
= 0; i
< num_users
; i
++) {
73 /* getutxent can return multiple user entries for the
74 * same user, so ignore any dups */
75 if (strcmp(u
->ut_user
, usr_infos
[i
].name
) == 0) {
83 tmp
= talloc_realloc(mem_ctx
, usr_infos
, struct usrinfo
,
91 usr_infos
[num_users
].name
= talloc_strdup(usr_infos
,
93 if (usr_infos
[num_users
].name
== NULL
) {
94 TALLOC_FREE(usr_infos
);
98 usr_infos
[num_users
].login_time
.tv_sec
= u
->ut_tv
.tv_sec
;
99 usr_infos
[num_users
].login_time
.tv_usec
= u
->ut_tv
.tv_usec
;
103 /* Sort the user list by time, oldest first */
104 TYPESAFE_QSORT(usr_infos
, num_users
, usr_info_cmp
);
106 users
= (char**)talloc_array(mem_ctx
, char*, num_users
);
108 for (i
= 0; i
< num_users
; i
++) {
109 users
[i
] = talloc_move(users
, &usr_infos
[i
].name
);
112 TALLOC_FREE(usr_infos
);
120 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
127 static int dom_user_cmp(const struct dom_usr
*usr1
, const struct dom_usr
*usr2
)
129 /* Called from qsort to compare two domain users in a dom_usr_t array
130 * for sorting by login time. Return >0 if usr1 login time was later
131 * than usr2 login time, <0 if it was earlier */
132 return (usr1
->login_time
- usr2
->login_time
);
135 /*******************************************************************
136 Get a list of the names of all users of this machine who are
137 logged into the domain.
139 This should return a list of the users on this machine who are
140 logged into the domain (i.e. have been authenticated by the domain's
141 password server) but that doesn't fit well with the normal Samba
142 scenario where accesses out to the domain are made through smbclient
143 with each such session individually authenticated. So about the best
144 we can do currently is to list sessions of local users connected to
145 this server, which means that to get themself included in the list a
146 local user must create a session to the local samba server by running:
147 smbclient \\\\localhost\\share
149 FIXME: find a better way to get local users logged into the domain
151 ********************************************************************/
153 static struct dom_usr
*get_domain_userlist(TALLOC_CTX
*mem_ctx
)
155 struct sessionid
*session_list
= NULL
;
156 char *machine_name
, *p
, *nm
;
158 struct dom_usr
*users
, *tmp
;
159 int i
, num_users
, num_sessions
;
161 sep
= lp_winbind_separator();
166 num_sessions
= list_sessions(mem_ctx
, &session_list
);
167 if (num_sessions
== 0) {
172 users
= talloc_array(mem_ctx
, struct dom_usr
, num_sessions
);
174 TALLOC_FREE(session_list
);
178 for (i
=num_users
=0; i
<num_sessions
; i
++) {
179 if (!session_list
[i
].username
180 || !session_list
[i
].remote_machine
) {
183 p
= strpbrk(session_list
[i
].remote_machine
, "./");
187 machine_name
= talloc_asprintf_strupper_m(
188 users
, "%s", session_list
[i
].remote_machine
);
189 if (machine_name
== NULL
) {
190 DEBUG(10, ("talloc_asprintf failed\n"));
193 if (strcmp(machine_name
, global_myname()) == 0) {
194 p
= session_list
[i
].username
;
198 * "domain+name" format so split domain and
203 users
[num_users
].domain
=
204 talloc_asprintf_strupper_m(users
,
206 users
[num_users
].name
= talloc_strdup(users
,
210 * Simple user name so get domain from smb.conf
212 users
[num_users
].domain
=
213 talloc_strdup(users
, lp_workgroup());
214 users
[num_users
].name
= talloc_strdup(users
,
217 users
[num_users
].login_time
=
218 session_list
[i
].connect_start
;
221 TALLOC_FREE(machine_name
);
223 TALLOC_FREE(session_list
);
225 tmp
= talloc_realloc(mem_ctx
, users
, struct dom_usr
, num_users
);
231 /* Sort the user list by time, oldest first */
232 TYPESAFE_QSORT(users
, num_users
, dom_user_cmp
);
238 /*******************************************************************
239 RPC Workstation Service request NetWkstaGetInfo with level 100.
240 Returns to the requester:
242 - The smb version number
244 Returns a filled in wkssvc_NetWkstaInfo100 struct.
245 ********************************************************************/
247 static struct wkssvc_NetWkstaInfo100
*create_wks_info_100(TALLOC_CTX
*mem_ctx
)
249 struct wkssvc_NetWkstaInfo100
*info100
;
251 info100
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo100
);
252 if (info100
== NULL
) {
256 info100
->platform_id
= PLATFORM_ID_NT
; /* unknown */
257 info100
->version_major
= lp_major_announce_version();
258 info100
->version_minor
= lp_minor_announce_version();
260 info100
->server_name
= talloc_asprintf_strupper_m(
261 info100
, "%s", global_myname());
262 info100
->domain_name
= talloc_asprintf_strupper_m(
263 info100
, "%s", lp_workgroup());
268 /*******************************************************************
269 RPC Workstation Service request NetWkstaGetInfo with level 101.
270 Returns to the requester:
271 - As per NetWkstaGetInfo with level 100, plus:
272 - The LANMAN directory path (not currently supported).
273 Returns a filled in wkssvc_NetWkstaInfo101 struct.
274 ********************************************************************/
276 static struct wkssvc_NetWkstaInfo101
*create_wks_info_101(TALLOC_CTX
*mem_ctx
)
278 struct wkssvc_NetWkstaInfo101
*info101
;
280 info101
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo101
);
281 if (info101
== NULL
) {
285 info101
->platform_id
= PLATFORM_ID_NT
; /* unknown */
286 info101
->version_major
= lp_major_announce_version();
287 info101
->version_minor
= lp_minor_announce_version();
289 info101
->server_name
= talloc_asprintf_strupper_m(
290 info101
, "%s", global_myname());
291 info101
->domain_name
= talloc_asprintf_strupper_m(
292 info101
, "%s", lp_workgroup());
293 info101
->lan_root
= "";
298 /*******************************************************************
299 RPC Workstation Service request NetWkstaGetInfo with level 102.
300 Returns to the requester:
301 - As per NetWkstaGetInfo with level 101, plus:
302 - The number of logged in users.
303 Returns a filled in wkssvc_NetWkstaInfo102 struct.
304 ********************************************************************/
306 static struct wkssvc_NetWkstaInfo102
*create_wks_info_102(TALLOC_CTX
*mem_ctx
)
308 struct wkssvc_NetWkstaInfo102
*info102
;
311 info102
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo102
);
312 if (info102
== NULL
) {
316 info102
->platform_id
= PLATFORM_ID_NT
; /* unknown */
317 info102
->version_major
= lp_major_announce_version();
318 info102
->version_minor
= lp_minor_announce_version();
320 info102
->server_name
= talloc_asprintf_strupper_m(
321 info102
, "%s", global_myname());
322 info102
->domain_name
= talloc_asprintf_strupper_m(
323 info102
, "%s", lp_workgroup());
324 info102
->lan_root
= "";
326 users
= get_logged_on_userlist(talloc_tos());
327 info102
->logged_on_users
= talloc_array_length(users
);
334 /********************************************************************
335 Handling for RPC Workstation Service request NetWkstaGetInfo
336 ********************************************************************/
338 WERROR
_wkssvc_NetWkstaGetInfo(pipes_struct
*p
, struct wkssvc_NetWkstaGetInfo
*r
)
340 switch (r
->in
.level
) {
342 /* Level 100 can be allowed from anyone including anonymous
343 * so no access checks are needed for this case */
344 r
->out
.info
->info100
= create_wks_info_100(p
->mem_ctx
);
345 if (r
->out
.info
->info100
== NULL
) {
350 /* Level 101 can be allowed from any logged in user */
351 if (!nt_token_check_sid(&global_sid_Authenticated_Users
,
352 p
->server_info
->ptok
)) {
353 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
355 DEBUGADD(3,(" - does not have sid for Authenticated "
358 &global_sid_Authenticated_Users
)));
359 debug_nt_user_token(DBGC_CLASS
, 3,
360 p
->server_info
->ptok
);
361 return WERR_ACCESS_DENIED
;
363 r
->out
.info
->info101
= create_wks_info_101(p
->mem_ctx
);
364 if (r
->out
.info
->info101
== NULL
) {
369 /* Level 102 Should only be allowed from a domain administrator */
370 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
371 p
->server_info
->ptok
)) {
372 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
374 DEBUGADD(3,(" - does not have sid for Administrators "
375 "group %s, sids are:\n",
376 sid_string_dbg(&global_sid_Builtin_Administrators
)));
377 debug_nt_user_token(DBGC_CLASS
, 3,
378 p
->server_info
->ptok
);
379 return WERR_ACCESS_DENIED
;
381 r
->out
.info
->info102
= create_wks_info_102(p
->mem_ctx
);
382 if (r
->out
.info
->info102
== NULL
) {
387 return WERR_UNKNOWN_LEVEL
;
393 /********************************************************************
394 ********************************************************************/
396 WERROR
_wkssvc_NetWkstaSetInfo(pipes_struct
*p
, struct wkssvc_NetWkstaSetInfo
*r
)
398 /* FIXME: Add implementation code here */
399 p
->rng_fault_state
= True
;
400 return WERR_NOT_SUPPORTED
;
403 /********************************************************************
404 RPC Workstation Service request NetWkstaEnumUsers with level 0:
405 Returns to the requester:
406 - the user names of the logged in users.
407 Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct.
408 ********************************************************************/
410 static struct wkssvc_NetWkstaEnumUsersCtr0
*create_enum_users0(
413 struct wkssvc_NetWkstaEnumUsersCtr0
*ctr0
;
417 ctr0
= talloc(mem_ctx
, struct wkssvc_NetWkstaEnumUsersCtr0
);
422 users
= get_logged_on_userlist(talloc_tos());
423 if (users
== NULL
&& errno
!= 0) {
424 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
425 errno
, strerror(errno
)));
430 num_users
= talloc_array_length(users
);
431 ctr0
->entries_read
= num_users
;
432 ctr0
->user0
= talloc_array(ctr0
, struct wkssvc_NetrWkstaUserInfo0
,
434 if (ctr0
->user0
== NULL
) {
440 for (i
=0; i
<num_users
; i
++) {
441 ctr0
->user0
[i
].user_name
= talloc_move(ctr0
->user0
, &users
[i
]);
447 /********************************************************************
448 RPC Workstation Service request NetWkstaEnumUsers with level 1.
449 Returns to the requester:
450 - the user names of the logged in users,
451 - the domain or machine each is logged into,
452 - the password server that was used to authenticate each,
453 - other domains each user is logged into (not currently supported).
454 Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct.
455 ********************************************************************/
457 static struct wkssvc_NetWkstaEnumUsersCtr1
*create_enum_users1(
460 struct wkssvc_NetWkstaEnumUsersCtr1
*ctr1
;
462 struct dom_usr
*dom_users
;
463 const char *pwd_server
;
465 int i
, j
, num_users
, num_dom_users
;
467 ctr1
= talloc(mem_ctx
, struct wkssvc_NetWkstaEnumUsersCtr1
);
472 users
= get_logged_on_userlist(talloc_tos());
473 if (users
== NULL
&& errno
!= 0) {
474 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
475 errno
, strerror(errno
)));
479 num_users
= talloc_array_length(users
);
481 dom_users
= get_domain_userlist(talloc_tos());
482 if (dom_users
== NULL
&& errno
!= 0) {
487 num_dom_users
= talloc_array_length(dom_users
);
489 ctr1
->user1
= talloc_array(ctr1
, struct wkssvc_NetrWkstaUserInfo1
,
490 num_users
+num_dom_users
);
491 if (ctr1
->user1
== NULL
) {
494 TALLOC_FREE(dom_users
);
500 if ((pwd_tmp
= talloc_strdup(ctr1
->user1
, lp_passwordserver()))) {
501 /* The configured password server is a full DNS name but
502 * for the logon server we need to return just the first
503 * component (machine name) of it in upper-case */
504 char *p
= strchr(pwd_tmp
, '.');
508 p
= pwd_tmp
+ strlen(pwd_tmp
);
510 while (--p
>= pwd_tmp
) {
513 pwd_server
= pwd_tmp
;
516 /* Put in local users first */
517 for (i
=0; i
<num_users
; i
++) {
518 ctr1
->user1
[i
].user_name
= talloc_move(ctr1
->user1
, &users
[i
]);
520 /* For a local user the domain name and logon server are
521 * both returned as the local machine's NetBIOS name */
522 ctr1
->user1
[i
].logon_domain
= ctr1
->user1
[i
].logon_server
=
523 talloc_asprintf_strupper_m(ctr1
->user1
, "%s", global_myname());
525 ctr1
->user1
[i
].other_domains
= NULL
; /* Maybe in future? */
528 /* Now domain users */
529 for (j
=0; j
<num_dom_users
; j
++) {
530 ctr1
->user1
[i
].user_name
=
531 talloc_strdup(ctr1
->user1
, dom_users
[j
].name
);
532 ctr1
->user1
[i
].logon_domain
=
533 talloc_strdup(ctr1
->user1
, dom_users
[j
].domain
);
534 ctr1
->user1
[i
].logon_server
= pwd_server
;
536 ctr1
->user1
[i
++].other_domains
= NULL
; /* Maybe in future? */
539 ctr1
->entries_read
= i
;
542 TALLOC_FREE(dom_users
);
546 /********************************************************************
547 Handling for RPC Workstation Service request NetWkstaEnumUsers
548 (a.k.a Windows NetWkstaUserEnum)
549 ********************************************************************/
551 WERROR
_wkssvc_NetWkstaEnumUsers(pipes_struct
*p
, struct wkssvc_NetWkstaEnumUsers
*r
)
553 /* This with any level should only be allowed from a domain administrator */
554 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
555 p
->server_info
->ptok
)) {
556 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
557 DEBUGADD(3,(" - does not have sid for Administrators group "
558 "%s\n", sid_string_dbg(
559 &global_sid_Builtin_Administrators
)));
560 debug_nt_user_token(DBGC_CLASS
, 3, p
->server_info
->ptok
);
561 return WERR_ACCESS_DENIED
;
564 switch (r
->in
.info
->level
) {
566 r
->out
.info
->ctr
.user0
= create_enum_users0(p
->mem_ctx
);
567 if (r
->out
.info
->ctr
.user0
== NULL
) {
570 r
->out
.info
->level
= r
->in
.info
->level
;
571 *r
->out
.entries_read
= r
->out
.info
->ctr
.user0
->entries_read
;
572 *r
->out
.resume_handle
= 0;
575 r
->out
.info
->ctr
.user1
= create_enum_users1(p
->mem_ctx
);
576 if (r
->out
.info
->ctr
.user1
== NULL
) {
579 r
->out
.info
->level
= r
->in
.info
->level
;
580 *r
->out
.entries_read
= r
->out
.info
->ctr
.user1
->entries_read
;
581 *r
->out
.resume_handle
= 0;
584 return WERR_UNKNOWN_LEVEL
;
590 /********************************************************************
591 ********************************************************************/
593 WERROR
_wkssvc_NetrWkstaUserGetInfo(pipes_struct
*p
, struct wkssvc_NetrWkstaUserGetInfo
*r
)
595 /* FIXME: Add implementation code here */
596 p
->rng_fault_state
= True
;
597 return WERR_NOT_SUPPORTED
;
600 /********************************************************************
601 ********************************************************************/
603 WERROR
_wkssvc_NetrWkstaUserSetInfo(pipes_struct
*p
, struct wkssvc_NetrWkstaUserSetInfo
*r
)
605 /* FIXME: Add implementation code here */
606 p
->rng_fault_state
= True
;
607 return WERR_NOT_SUPPORTED
;
610 /********************************************************************
611 ********************************************************************/
613 WERROR
_wkssvc_NetWkstaTransportEnum(pipes_struct
*p
, struct wkssvc_NetWkstaTransportEnum
*r
)
615 /* FIXME: Add implementation code here */
616 p
->rng_fault_state
= True
;
617 return WERR_NOT_SUPPORTED
;
620 /********************************************************************
621 ********************************************************************/
623 WERROR
_wkssvc_NetrWkstaTransportAdd(pipes_struct
*p
, struct wkssvc_NetrWkstaTransportAdd
*r
)
625 /* FIXME: Add implementation code here */
626 p
->rng_fault_state
= True
;
627 return WERR_NOT_SUPPORTED
;
630 /********************************************************************
631 ********************************************************************/
633 WERROR
_wkssvc_NetrWkstaTransportDel(pipes_struct
*p
, struct wkssvc_NetrWkstaTransportDel
*r
)
635 /* FIXME: Add implementation code here */
636 p
->rng_fault_state
= True
;
637 return WERR_NOT_SUPPORTED
;
640 /********************************************************************
641 ********************************************************************/
643 WERROR
_wkssvc_NetrUseAdd(pipes_struct
*p
, struct wkssvc_NetrUseAdd
*r
)
645 /* FIXME: Add implementation code here */
646 p
->rng_fault_state
= True
;
647 return WERR_NOT_SUPPORTED
;
650 /********************************************************************
651 ********************************************************************/
653 WERROR
_wkssvc_NetrUseGetInfo(pipes_struct
*p
, struct wkssvc_NetrUseGetInfo
*r
)
655 /* FIXME: Add implementation code here */
656 p
->rng_fault_state
= True
;
657 return WERR_NOT_SUPPORTED
;
660 /********************************************************************
661 ********************************************************************/
663 WERROR
_wkssvc_NetrUseDel(pipes_struct
*p
, struct wkssvc_NetrUseDel
*r
)
665 /* FIXME: Add implementation code here */
666 p
->rng_fault_state
= True
;
667 return WERR_NOT_SUPPORTED
;
670 /********************************************************************
671 ********************************************************************/
673 WERROR
_wkssvc_NetrUseEnum(pipes_struct
*p
, struct wkssvc_NetrUseEnum
*r
)
675 /* FIXME: Add implementation code here */
676 p
->rng_fault_state
= True
;
677 return WERR_NOT_SUPPORTED
;
680 /********************************************************************
681 ********************************************************************/
683 WERROR
_wkssvc_NetrMessageBufferSend(pipes_struct
*p
, struct wkssvc_NetrMessageBufferSend
*r
)
685 /* FIXME: Add implementation code here */
686 p
->rng_fault_state
= True
;
687 return WERR_NOT_SUPPORTED
;
690 /********************************************************************
691 ********************************************************************/
693 WERROR
_wkssvc_NetrWorkstationStatisticsGet(pipes_struct
*p
, struct wkssvc_NetrWorkstationStatisticsGet
*r
)
695 /* FIXME: Add implementation code here */
696 p
->rng_fault_state
= True
;
697 return WERR_NOT_SUPPORTED
;
700 /********************************************************************
701 ********************************************************************/
703 WERROR
_wkssvc_NetrLogonDomainNameAdd(pipes_struct
*p
, struct wkssvc_NetrLogonDomainNameAdd
*r
)
705 /* FIXME: Add implementation code here */
706 p
->rng_fault_state
= True
;
707 return WERR_NOT_SUPPORTED
;
710 /********************************************************************
711 ********************************************************************/
713 WERROR
_wkssvc_NetrLogonDomainNameDel(pipes_struct
*p
, struct wkssvc_NetrLogonDomainNameDel
*r
)
715 /* FIXME: Add implementation code here */
716 p
->rng_fault_state
= True
;
717 return WERR_NOT_SUPPORTED
;
720 /********************************************************************
721 ********************************************************************/
723 WERROR
_wkssvc_NetrJoinDomain(pipes_struct
*p
, struct wkssvc_NetrJoinDomain
*r
)
725 /* FIXME: Add implementation code here */
726 p
->rng_fault_state
= True
;
727 return WERR_NOT_SUPPORTED
;
730 /********************************************************************
731 ********************************************************************/
733 WERROR
_wkssvc_NetrUnjoinDomain(pipes_struct
*p
, struct wkssvc_NetrUnjoinDomain
*r
)
735 /* FIXME: Add implementation code here */
736 p
->rng_fault_state
= True
;
737 return WERR_NOT_SUPPORTED
;
740 /********************************************************************
741 ********************************************************************/
743 WERROR
_wkssvc_NetrRenameMachineInDomain(pipes_struct
*p
, struct wkssvc_NetrRenameMachineInDomain
*r
)
745 /* FIXME: Add implementation code here */
746 p
->rng_fault_state
= True
;
747 return WERR_NOT_SUPPORTED
;
750 /********************************************************************
751 ********************************************************************/
753 WERROR
_wkssvc_NetrValidateName(pipes_struct
*p
, struct wkssvc_NetrValidateName
*r
)
755 /* FIXME: Add implementation code here */
756 p
->rng_fault_state
= True
;
757 return WERR_NOT_SUPPORTED
;
760 /********************************************************************
761 ********************************************************************/
763 WERROR
_wkssvc_NetrGetJoinInformation(pipes_struct
*p
, struct wkssvc_NetrGetJoinInformation
*r
)
765 /* FIXME: Add implementation code here */
766 p
->rng_fault_state
= True
;
767 return WERR_NOT_SUPPORTED
;
770 /********************************************************************
771 ********************************************************************/
773 WERROR
_wkssvc_NetrGetJoinableOus(pipes_struct
*p
, struct wkssvc_NetrGetJoinableOus
*r
)
775 /* FIXME: Add implementation code here */
776 p
->rng_fault_state
= True
;
777 return WERR_NOT_SUPPORTED
;
780 /********************************************************************
781 _wkssvc_NetrJoinDomain2
782 ********************************************************************/
784 WERROR
_wkssvc_NetrJoinDomain2(pipes_struct
*p
,
785 struct wkssvc_NetrJoinDomain2
*r
)
787 struct libnet_JoinCtx
*j
= NULL
;
788 char *cleartext_pwd
= NULL
;
789 char *admin_domain
= NULL
;
790 char *admin_account
= NULL
;
792 struct nt_user_token
*token
= p
->server_info
->ptok
;
794 if (!r
->in
.domain_name
) {
795 return WERR_INVALID_PARAM
;
798 if (!r
->in
.admin_account
|| !r
->in
.encrypted_password
) {
799 return WERR_INVALID_PARAM
;
802 if (!user_has_privileges(token
, &se_machine_account
) &&
803 !nt_token_check_domain_rid(token
, DOMAIN_RID_ADMINS
) &&
804 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
805 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
806 "sufficient privileges\n"));
807 return WERR_ACCESS_DENIED
;
810 if ((r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED
) ||
811 (r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_JOIN_UNSECURE
)) {
812 return WERR_NOT_SUPPORTED
;
815 werr
= decode_wkssvc_join_password_buffer(
816 p
->mem_ctx
, r
->in
.encrypted_password
,
817 &p
->server_info
->user_session_key
, &cleartext_pwd
);
818 if (!W_ERROR_IS_OK(werr
)) {
822 split_domain_user(p
->mem_ctx
,
827 werr
= libnet_init_JoinCtx(p
->mem_ctx
, &j
);
828 if (!W_ERROR_IS_OK(werr
)) {
832 j
->in
.domain_name
= r
->in
.domain_name
;
833 j
->in
.account_ou
= r
->in
.account_ou
;
834 j
->in
.join_flags
= r
->in
.join_flags
;
835 j
->in
.admin_account
= admin_account
;
836 j
->in
.admin_password
= cleartext_pwd
;
838 j
->in
.modify_config
= lp_config_backend_is_registry();
839 j
->in
.msg_ctx
= smbd_messaging_context();
842 werr
= libnet_Join(p
->mem_ctx
, j
);
845 if (!W_ERROR_IS_OK(werr
)) {
846 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
847 j
->out
.error_string
? j
->out
.error_string
:
855 /********************************************************************
856 _wkssvc_NetrUnjoinDomain2
857 ********************************************************************/
859 WERROR
_wkssvc_NetrUnjoinDomain2(pipes_struct
*p
,
860 struct wkssvc_NetrUnjoinDomain2
*r
)
862 struct libnet_UnjoinCtx
*u
= NULL
;
863 char *cleartext_pwd
= NULL
;
864 char *admin_domain
= NULL
;
865 char *admin_account
= NULL
;
867 struct nt_user_token
*token
= p
->server_info
->ptok
;
869 if (!r
->in
.account
|| !r
->in
.encrypted_password
) {
870 return WERR_INVALID_PARAM
;
873 if (!user_has_privileges(token
, &se_machine_account
) &&
874 !nt_token_check_domain_rid(token
, DOMAIN_RID_ADMINS
) &&
875 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
876 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
877 "sufficient privileges\n"));
878 return WERR_ACCESS_DENIED
;
881 werr
= decode_wkssvc_join_password_buffer(
882 p
->mem_ctx
, r
->in
.encrypted_password
,
883 &p
->server_info
->user_session_key
, &cleartext_pwd
);
884 if (!W_ERROR_IS_OK(werr
)) {
888 split_domain_user(p
->mem_ctx
,
893 werr
= libnet_init_UnjoinCtx(p
->mem_ctx
, &u
);
894 if (!W_ERROR_IS_OK(werr
)) {
898 u
->in
.domain_name
= lp_realm();
899 u
->in
.unjoin_flags
= r
->in
.unjoin_flags
|
900 WKSSVC_JOIN_FLAGS_JOIN_TYPE
;
901 u
->in
.admin_account
= admin_account
;
902 u
->in
.admin_password
= cleartext_pwd
;
904 u
->in
.modify_config
= lp_config_backend_is_registry();
905 u
->in
.msg_ctx
= smbd_messaging_context();
908 werr
= libnet_Unjoin(p
->mem_ctx
, u
);
911 if (!W_ERROR_IS_OK(werr
)) {
912 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
913 u
->out
.error_string
? u
->out
.error_string
:
921 /********************************************************************
922 ********************************************************************/
924 WERROR
_wkssvc_NetrRenameMachineInDomain2(pipes_struct
*p
, struct wkssvc_NetrRenameMachineInDomain2
*r
)
926 /* for now just return not supported */
927 return WERR_NOT_SUPPORTED
;
930 /********************************************************************
931 ********************************************************************/
933 WERROR
_wkssvc_NetrValidateName2(pipes_struct
*p
, struct wkssvc_NetrValidateName2
*r
)
935 /* FIXME: Add implementation code here */
936 p
->rng_fault_state
= True
;
937 return WERR_NOT_SUPPORTED
;
940 /********************************************************************
941 ********************************************************************/
943 WERROR
_wkssvc_NetrGetJoinableOus2(pipes_struct
*p
, struct wkssvc_NetrGetJoinableOus2
*r
)
945 /* FIXME: Add implementation code here */
946 p
->rng_fault_state
= True
;
947 return WERR_NOT_SUPPORTED
;
950 /********************************************************************
951 ********************************************************************/
953 WERROR
_wkssvc_NetrAddAlternateComputerName(pipes_struct
*p
, struct wkssvc_NetrAddAlternateComputerName
*r
)
955 /* FIXME: Add implementation code here */
956 p
->rng_fault_state
= True
;
957 return WERR_NOT_SUPPORTED
;
960 /********************************************************************
961 ********************************************************************/
963 WERROR
_wkssvc_NetrRemoveAlternateComputerName(pipes_struct
*p
, struct wkssvc_NetrRemoveAlternateComputerName
*r
)
965 /* FIXME: Add implementation code here */
966 p
->rng_fault_state
= True
;
967 return WERR_NOT_SUPPORTED
;
970 /********************************************************************
971 ********************************************************************/
973 WERROR
_wkssvc_NetrSetPrimaryComputername(pipes_struct
*p
, struct wkssvc_NetrSetPrimaryComputername
*r
)
975 /* FIXME: Add implementation code here */
976 p
->rng_fault_state
= True
;
977 return WERR_NOT_SUPPORTED
;
980 /********************************************************************
981 ********************************************************************/
983 WERROR
_wkssvc_NetrEnumerateComputerNames(pipes_struct
*p
, struct wkssvc_NetrEnumerateComputerNames
*r
)
985 /* FIXME: Add implementation code here */
986 p
->rng_fault_state
= True
;
987 return WERR_NOT_SUPPORTED
;