s4-kdc: make DB_GLUE a private library
[Samba.git] / source3 / rpc_server / srv_wkssvc_nt.c
blob000b605913d7099e61dfd221eb652150b7660b11
1 /*
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. */
25 #include "includes.h"
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"
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_RPC_SRV
35 struct dom_usr {
36 char *name;
37 char *domain;
38 time_t login_time;
41 #ifdef HAVE_GETUTXENT
43 #include <utmpx.h>
45 struct usrinfo {
46 char *name;
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)
64 char **users;
65 int i, num_users = 0;
66 struct usrinfo *usr_infos = NULL;
67 struct utmpx *u;
69 while ((u = getutxent()) != NULL) {
70 struct usrinfo *tmp;
71 if (u->ut_type != USER_PROCESS) {
72 continue;
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) {
78 break;
81 if (i < num_users) {
82 continue;
85 tmp = talloc_realloc(mem_ctx, usr_infos, struct usrinfo,
86 num_users+1);
87 if (tmp == NULL) {
88 TALLOC_FREE(tmp);
89 endutxent();
90 return NULL;
92 usr_infos = tmp;
93 usr_infos[num_users].name = talloc_strdup(usr_infos,
94 u->ut_user);
95 if (usr_infos[num_users].name == NULL) {
96 TALLOC_FREE(usr_infos);
97 endutxent();
98 return NULL;
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;
102 num_users += 1;
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);
109 if (users) {
110 for (i = 0; i < num_users; i++) {
111 users[i] = talloc_move(users, &usr_infos[i].name);
114 TALLOC_FREE(usr_infos);
115 endutxent();
116 errno = 0;
117 return users;
120 #else
122 static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx)
124 return NULL;
127 #endif
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
152 in this list.
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;
159 const char *sep;
160 struct dom_usr *users, *tmp;
161 int i, num_users, num_sessions;
163 sep = lp_winbind_separator();
164 if (!sep) {
165 sep = "\\";
168 num_sessions = list_sessions(mem_ctx, &session_list);
169 if (num_sessions == 0) {
170 errno = 0;
171 return NULL;
174 users = talloc_array(mem_ctx, struct dom_usr, num_sessions);
175 if (users == NULL) {
176 TALLOC_FREE(session_list);
177 return NULL;
180 for (i=num_users=0; i<num_sessions; i++) {
181 if (!session_list[i].username
182 || !session_list[i].remote_machine) {
183 continue;
185 p = strpbrk(session_list[i].remote_machine, "./");
186 if (p) {
187 *p = '\0';
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"));
193 continue;
195 if (strcmp(machine_name, global_myname()) == 0) {
196 p = session_list[i].username;
197 nm = strstr(p, sep);
198 if (nm) {
200 * "domain+name" format so split domain and
201 * name components
203 *nm = '\0';
204 nm += strlen(sep);
205 users[num_users].domain =
206 talloc_asprintf_strupper_m(users,
207 "%s", p);
208 users[num_users].name = talloc_strdup(users,
209 nm);
210 } else {
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;
221 num_users++;
223 TALLOC_FREE(machine_name);
225 TALLOC_FREE(session_list);
227 tmp = talloc_realloc(mem_ctx, users, struct dom_usr, num_users);
228 if (tmp == NULL) {
229 return NULL;
231 users = tmp;
233 /* Sort the user list by time, oldest first */
234 TYPESAFE_QSORT(users, num_users, dom_user_cmp);
236 errno = 0;
237 return users;
240 /*******************************************************************
241 RPC Workstation Service request NetWkstaGetInfo with level 100.
242 Returns to the requester:
243 - The machine name.
244 - The smb version number
245 - The domain name.
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) {
255 return 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());
267 return info100;
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) {
284 return 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 = "";
297 return info101;
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;
311 char **users;
313 info102 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo102);
314 if (info102 == NULL) {
315 return 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);
331 TALLOC_FREE(users);
333 return info102;
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) {
344 case 100:
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) {
349 return WERR_NOMEM;
351 break;
352 case 101:
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 "
357 "101\n"));
358 DEBUGADD(3,(" - does not have sid for Authenticated "
359 "Users %s:\n",
360 sid_string_dbg(
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) {
368 return WERR_NOMEM;
370 break;
371 case 102:
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 "
376 "102\n"));
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) {
386 return WERR_NOMEM;
388 break;
389 default:
390 return WERR_UNKNOWN_LEVEL;
393 return WERR_OK;
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(
415 TALLOC_CTX *mem_ctx)
417 struct wkssvc_NetWkstaEnumUsersCtr0 *ctr0;
418 char **users;
419 int i, num_users;
421 ctr0 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr0);
422 if (ctr0 == NULL) {
423 return NULL;
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)));
430 TALLOC_FREE(ctr0);
431 return NULL;
434 num_users = talloc_array_length(users);
435 ctr0->entries_read = num_users;
436 ctr0->user0 = talloc_array(ctr0, struct wkssvc_NetrWkstaUserInfo0,
437 num_users);
438 if (ctr0->user0 == NULL) {
439 TALLOC_FREE(ctr0);
440 TALLOC_FREE(users);
441 return NULL;
444 for (i=0; i<num_users; i++) {
445 ctr0->user0[i].user_name = talloc_move(ctr0->user0, &users[i]);
447 TALLOC_FREE(users);
448 return ctr0;
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(
462 TALLOC_CTX *mem_ctx)
464 struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1;
465 char **users;
466 struct dom_usr *dom_users;
467 const char *pwd_server;
468 char *pwd_tmp;
469 int i, j, num_users, num_dom_users;
471 ctr1 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr1);
472 if (ctr1 == NULL) {
473 return NULL;
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)));
480 TALLOC_FREE(ctr1);
481 return NULL;
483 num_users = talloc_array_length(users);
485 dom_users = get_domain_userlist(talloc_tos());
486 if (dom_users == NULL && errno != 0) {
487 TALLOC_FREE(ctr1);
488 TALLOC_FREE(users);
489 return NULL;
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) {
496 TALLOC_FREE(ctr1);
497 TALLOC_FREE(users);
498 TALLOC_FREE(dom_users);
499 return NULL;
502 pwd_server = "";
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, '.');
509 if (p) {
510 *p = '\0';
511 } else {
512 p = pwd_tmp + strlen(pwd_tmp);
514 while (--p >= pwd_tmp) {
515 *p = toupper(*p);
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;
545 TALLOC_FREE(users);
546 TALLOC_FREE(dom_users);
547 return ctr1;
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) {
570 case 0:
571 r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx);
572 if (r->out.info->ctr.user0 == NULL) {
573 return WERR_NOMEM;
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;
578 break;
579 case 1:
580 r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx);
581 if (r->out.info->ctr.user1 == NULL) {
582 return WERR_NOMEM;
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;
587 break;
588 default:
589 return WERR_UNKNOWN_LEVEL;
592 return WERR_OK;
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;
815 WERROR werr;
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)) {
843 return werr;
846 split_domain_user(p->mem_ctx,
847 r->in.admin_account,
848 &admin_domain,
849 &admin_account);
851 werr = libnet_init_JoinCtx(p->mem_ctx, &j);
852 if (!W_ERROR_IS_OK(werr)) {
853 return 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;
861 j->in.debug = true;
862 j->in.modify_config = lp_config_backend_is_registry();
863 j->in.msg_ctx = p->msg_ctx;
865 become_root();
866 werr = libnet_Join(p->mem_ctx, j);
867 unbecome_root();
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 :
872 win_errstr(werr)));
875 TALLOC_FREE(j);
876 return werr;
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;
890 WERROR werr;
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)) {
909 return werr;
912 split_domain_user(p->mem_ctx,
913 r->in.account,
914 &admin_domain,
915 &admin_account);
917 werr = libnet_init_UnjoinCtx(p->mem_ctx, &u);
918 if (!W_ERROR_IS_OK(werr)) {
919 return 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;
927 u->in.debug = true;
928 u->in.modify_config = lp_config_backend_is_registry();
929 u->in.msg_ctx = p->msg_ctx;
931 become_root();
932 werr = libnet_Unjoin(p->mem_ctx, u);
933 unbecome_root();
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 :
938 win_errstr(werr)));
941 TALLOC_FREE(u);
942 return werr;
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;