LCOV - code coverage report
Current view: top level - source3/rpc_server/wkssvc - srv_wkssvc_nt.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 190 404 47.0 %
Date: 2024-04-13 12:30:31 Functions: 29 38 76.3 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *
       5             :  *  Copyright (C) Andrew Tridgell               1992-1997,
       6             :  *  Copyright (C) Gerald (Jerry) Carter         2006.
       7             :  *  Copyright (C) Guenther Deschner             2007-2008.
       8             :  *
       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.
      13             :  *
      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.
      18             :  *
      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/>.
      21             :  */
      22             : 
      23             : /* This is the implementation of the wks interface. */
      24             : 
      25             : #include "includes.h"
      26             : #include "ntdomain.h"
      27             : #include "librpc/rpc/dcesrv_core.h"
      28             : #include "librpc/gen_ndr/libnet_join.h"
      29             : #include "libnet/libnet_join.h"
      30             : #include "../libcli/auth/libcli_auth.h"
      31             : #include "librpc/gen_ndr/ndr_wkssvc.h"
      32             : #include "librpc/gen_ndr/ndr_wkssvc_scompat.h"
      33             : #include "../libcli/security/security.h"
      34             : #include "session.h"
      35             : #include "smbd/smbd.h"
      36             : #include "auth.h"
      37             : #include "krb5_env.h"
      38             : 
      39             : #undef DBGC_CLASS
      40             : #define DBGC_CLASS DBGC_RPC_SRV
      41             : 
      42             : struct dom_usr {
      43             :         char *name;
      44             :         char *domain;
      45             :         time_t login_time;
      46             : };
      47             : 
      48           0 : static int dom_user_cmp(const struct dom_usr *usr1, const struct dom_usr *usr2)
      49             : {
      50             :         /* Called from qsort to compare two domain users in a dom_usr_t array
      51             :          * for sorting by login time. Return >0 if usr1 login time was later
      52             :          * than usr2 login time, <0 if it was earlier */
      53           0 :         return (usr1->login_time - usr2->login_time);
      54             : }
      55             : 
      56             : /*******************************************************************
      57             :  Get a list of the names of all users of this machine who are
      58             :  logged into the domain.
      59             : 
      60             :  This should return a list of the users on this machine who are
      61             :  logged into the domain (i.e. have been authenticated by the domain's
      62             :  password server) but that doesn't fit well with the normal Samba
      63             :  scenario where accesses out to the domain are made through smbclient
      64             :  with each such session individually authenticated. So about the best
      65             :  we can do currently is to list sessions of local users connected to
      66             :  this server, which means that to get themself included in the list a
      67             :  local user must create a session to the local samba server by running:
      68             :      smbclient \\\\localhost\\share
      69             : 
      70             :  FIXME: find a better way to get local users logged into the domain
      71             :  in this list.
      72             :  ********************************************************************/
      73             : 
      74           2 : static int get_domain_userlist(TALLOC_CTX *mem_ctx, struct dom_usr **pusers)
      75             : {
      76           2 :         struct sessionid *session_list = NULL;
      77           0 :         char *machine_name, *p, *nm;
      78           0 :         const char *sep;
      79           0 :         struct dom_usr *users, *tmp;
      80           0 :         int i, num_users, num_sessions;
      81             : 
      82           2 :         sep = lp_winbind_separator();
      83           2 :         if (!sep) {
      84           0 :                 sep = "\\";
      85             :         }
      86             : 
      87           2 :         num_sessions = list_sessions(mem_ctx, &session_list);
      88           2 :         if (num_sessions == 0) {
      89           0 :                 *pusers = NULL;
      90           0 :                 return 0;
      91             :         }
      92             : 
      93           2 :         users = talloc_array(mem_ctx, struct dom_usr, num_sessions);
      94           2 :         if (users == NULL) {
      95           0 :                 TALLOC_FREE(session_list);
      96           0 :                 return ENOMEM;
      97             :         }
      98             : 
      99           4 :         for (i=num_users=0; i<num_sessions; i++) {
     100           2 :                 if (session_list[i].username[0] == '\0' ||
     101           2 :                     session_list[i].remote_machine[0] == '\0') {
     102           0 :                         continue;
     103             :                 }
     104           2 :                 p = strpbrk(session_list[i].remote_machine, "./");
     105           2 :                 if (p) {
     106           2 :                         *p = '\0';
     107             :                 }
     108           2 :                 machine_name = talloc_asprintf_strupper_m(
     109           2 :                         users, "%s", session_list[i].remote_machine);
     110           2 :                 if (machine_name == NULL) {
     111           0 :                         DEBUG(10, ("talloc_asprintf failed\n"));
     112           0 :                         continue;
     113             :                 }
     114           2 :                 if (strcmp(machine_name, lp_netbios_name()) == 0) {
     115           0 :                         p = session_list[i].username;
     116           0 :                         nm = strstr(p, sep);
     117           0 :                         if (nm) {
     118             :                                 /*
     119             :                                  * "domain+name" format so split domain and
     120             :                                  * name components
     121             :                                  */
     122           0 :                                 *nm = '\0';
     123           0 :                                 nm += strlen(sep);
     124           0 :                                 users[num_users].domain =
     125           0 :                                         talloc_asprintf_strupper_m(users,
     126             :                                                                    "%s", p);
     127           0 :                                 users[num_users].name = talloc_strdup(users,
     128             :                                                                       nm);
     129             :                         } else {
     130             :                                 /*
     131             :                                  * Simple user name so get domain from smb.conf
     132             :                                  */
     133           0 :                                 users[num_users].domain =
     134           0 :                                         talloc_strdup(users, lp_workgroup());
     135           0 :                                 users[num_users].name = talloc_strdup(users,
     136             :                                                                       p);
     137             :                         }
     138           0 :                         users[num_users].login_time =
     139           0 :                                 session_list[i].connect_start;
     140           0 :                         num_users++;
     141             :                 }
     142           2 :                 TALLOC_FREE(machine_name);
     143             :         }
     144           2 :         TALLOC_FREE(session_list);
     145             : 
     146           2 :         if (num_users == 0) {
     147           2 :                 TALLOC_FREE(users);
     148           2 :                 *pusers = NULL;
     149           2 :                 return 0;
     150             :         }
     151             : 
     152           0 :         tmp = talloc_realloc(mem_ctx, users, struct dom_usr, num_users);
     153           0 :         if (tmp == NULL) {
     154           0 :                 TALLOC_FREE(users);
     155           0 :                 return ENOMEM;
     156             :         }
     157           0 :         users = tmp;
     158             : 
     159             :         /* Sort the user list by time, oldest first */
     160           0 :         TYPESAFE_QSORT(users, num_users, dom_user_cmp);
     161             : 
     162           0 :         *pusers = users;
     163           0 :         return 0;
     164             : }
     165             : 
     166             : /*******************************************************************
     167             :  RPC Workstation Service request NetWkstaGetInfo with level 100.
     168             :  Returns to the requester:
     169             :   - The machine name.
     170             :   - The smb version number
     171             :   - The domain name.
     172             :  Returns a filled in wkssvc_NetWkstaInfo100 struct.
     173             :  ********************************************************************/
     174             : 
     175           4 : static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx)
     176             : {
     177           0 :         struct wkssvc_NetWkstaInfo100 *info100;
     178             : 
     179           4 :         info100 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo100);
     180           4 :         if (info100 == NULL) {
     181           0 :                 return NULL;
     182             :         }
     183             : 
     184           4 :         info100->platform_id  = PLATFORM_ID_NT;      /* unknown */
     185           4 :         info100->version_major        = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
     186           4 :         info100->version_minor        = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
     187             : 
     188           4 :         info100->server_name = talloc_asprintf_strupper_m(
     189             :                 info100, "%s", lp_netbios_name());
     190           4 :         info100->domain_name = talloc_asprintf_strupper_m(
     191             :                 info100, "%s", lp_workgroup());
     192             : 
     193           4 :         return info100;
     194             : }
     195             : 
     196             : /*******************************************************************
     197             :  RPC Workstation Service request NetWkstaGetInfo with level 101.
     198             :  Returns to the requester:
     199             :   - As per NetWkstaGetInfo with level 100, plus:
     200             :   - The LANMAN directory path (not currently supported).
     201             :  Returns a filled in wkssvc_NetWkstaInfo101 struct.
     202             :  ********************************************************************/
     203             : 
     204           2 : static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx)
     205             : {
     206           0 :         struct wkssvc_NetWkstaInfo101 *info101;
     207             : 
     208           2 :         info101 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo101);
     209           2 :         if (info101 == NULL) {
     210           0 :                 return NULL;
     211             :         }
     212             : 
     213           2 :         info101->platform_id  = PLATFORM_ID_NT;      /* unknown */
     214           2 :         info101->version_major        = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
     215           2 :         info101->version_minor        = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
     216             : 
     217           2 :         info101->server_name = talloc_asprintf_strupper_m(
     218             :                 info101, "%s", lp_netbios_name());
     219           2 :         info101->domain_name = talloc_asprintf_strupper_m(
     220             :                 info101, "%s", lp_workgroup());
     221           2 :         info101->lan_root = "";
     222             : 
     223           2 :         return info101;
     224             : }
     225             : 
     226             : /*******************************************************************
     227             :  RPC Workstation Service request NetWkstaGetInfo with level 102.
     228             :  Returns to the requester:
     229             :   - As per NetWkstaGetInfo with level 101, plus:
     230             :   - The number of logged in users.
     231             :  Returns a filled in wkssvc_NetWkstaInfo102 struct.
     232             :  ********************************************************************/
     233             : 
     234           2 : static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx)
     235             : {
     236           0 :         struct wkssvc_NetWkstaInfo102 *info102;
     237             : 
     238           2 :         info102 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo102);
     239           2 :         if (info102 == NULL) {
     240           0 :                 return NULL;
     241             :         }
     242             : 
     243           2 :         info102->platform_id  = PLATFORM_ID_NT;      /* unknown */
     244           2 :         info102->version_major        = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
     245           2 :         info102->version_minor        = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
     246             : 
     247           2 :         info102->server_name = talloc_asprintf_strupper_m(
     248             :                 info102, "%s", lp_netbios_name());
     249           2 :         info102->domain_name = talloc_asprintf_strupper_m(
     250             :                 info102, "%s", lp_workgroup());
     251           2 :         info102->lan_root = "";
     252           2 :         info102->logged_on_users = 0;
     253             : 
     254           2 :         return info102;
     255             : }
     256             : 
     257             : /********************************************************************
     258             :  Handling for RPC Workstation Service request NetWkstaGetInfo
     259             :  ********************************************************************/
     260             : 
     261          10 : WERROR _wkssvc_NetWkstaGetInfo(struct pipes_struct *p,
     262             :                                struct wkssvc_NetWkstaGetInfo *r)
     263             : {
     264          10 :         struct dcesrv_call_state *dce_call = p->dce_call;
     265           0 :         struct auth_session_info *session_info =
     266          10 :                 dcesrv_call_session_info(dce_call);
     267           0 :         struct dom_sid_buf buf;
     268             : 
     269          10 :         switch (r->in.level) {
     270           4 :         case 100:
     271             :                 /* Level 100 can be allowed from anyone including anonymous
     272             :                  * so no access checks are needed for this case */
     273           4 :                 r->out.info->info100 = create_wks_info_100(p->mem_ctx);
     274           4 :                 if (r->out.info->info100 == NULL) {
     275           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     276             :                 }
     277           4 :                 break;
     278           2 :         case 101:
     279             :                 /* Level 101 can be allowed from any logged in user */
     280           2 :                 if (!nt_token_check_sid(&global_sid_Authenticated_Users,
     281           2 :                                         session_info->security_token)) {
     282           0 :                         DEBUG(1,("User not allowed for NetWkstaGetInfo level "
     283             :                                  "101\n"));
     284           0 :                         DEBUGADD(3,(" - does not have sid for Authenticated "
     285             :                                     "Users %s:\n",
     286             :                                     dom_sid_str_buf(
     287             :                                             &global_sid_Authenticated_Users,
     288             :                                             &buf)));
     289           0 :                         security_token_debug(DBGC_CLASS, 3,
     290           0 :                                             session_info->security_token);
     291           0 :                         return WERR_ACCESS_DENIED;
     292             :                 }
     293           2 :                 r->out.info->info101 = create_wks_info_101(p->mem_ctx);
     294           2 :                 if (r->out.info->info101 == NULL) {
     295           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     296             :                 }
     297           2 :                 break;
     298           2 :         case 102:
     299             :                 /* Level 102 Should only be allowed from a domain administrator */
     300           2 :                 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
     301           2 :                                         session_info->security_token)) {
     302           0 :                         DEBUG(1,("User not allowed for NetWkstaGetInfo level "
     303             :                                  "102\n"));
     304           0 :                         DEBUGADD(3,(" - does not have sid for Administrators "
     305             :                                     "group %s, sids are:\n",
     306             :                                     dom_sid_str_buf(
     307             :                                             &global_sid_Builtin_Administrators,
     308             :                                             &buf)));
     309           0 :                         security_token_debug(DBGC_CLASS, 3,
     310           0 :                                             session_info->security_token);
     311           0 :                         return WERR_ACCESS_DENIED;
     312             :                 }
     313           2 :                 r->out.info->info102 = create_wks_info_102(p->mem_ctx);
     314           2 :                 if (r->out.info->info102 == NULL) {
     315           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     316             :                 }
     317           2 :                 break;
     318           2 :         default:
     319           2 :                 return WERR_INVALID_LEVEL;
     320             :         }
     321             : 
     322           8 :         return WERR_OK;
     323             : }
     324             : 
     325             : /********************************************************************
     326             :  ********************************************************************/
     327             : 
     328           0 : WERROR _wkssvc_NetWkstaSetInfo(struct pipes_struct *p,
     329             :                                struct wkssvc_NetWkstaSetInfo *r)
     330             : {
     331             :         /* FIXME: Add implementation code here */
     332           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     333           0 :         return WERR_NOT_SUPPORTED;
     334             : }
     335             : 
     336             : /********************************************************************
     337             :  RPC Workstation Service request NetWkstaEnumUsers with level 0:
     338             :  Returns to the requester:
     339             :   - the user names of the logged in users.
     340             :  Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct.
     341             :  ********************************************************************/
     342             : 
     343           2 : static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0(
     344             :         TALLOC_CTX *mem_ctx)
     345             : {
     346           0 :         struct wkssvc_NetWkstaEnumUsersCtr0 *ctr0;
     347             : 
     348           2 :         ctr0 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr0);
     349           2 :         if (ctr0 == NULL) {
     350           0 :                 return NULL;
     351             :         }
     352             : 
     353           2 :         ctr0->entries_read = 0;
     354           2 :         ctr0->user0 = talloc_array(ctr0, struct wkssvc_NetrWkstaUserInfo0, 0);
     355           2 :         if (ctr0->user0 == NULL) {
     356           0 :                 TALLOC_FREE(ctr0);
     357           0 :                 return NULL;
     358             :         }
     359             : 
     360           2 :         return ctr0;
     361             : }
     362             : 
     363             : /********************************************************************
     364             :  RPC Workstation Service request NetWkstaEnumUsers with level 1.
     365             :  Returns to the requester:
     366             :   - the user names of the logged in users,
     367             :   - the domain or machine each is logged into,
     368             :   - the password server that was used to authenticate each,
     369             :   - other domains each user is logged into (not currently supported).
     370             :  Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct.
     371             :  ********************************************************************/
     372             : 
     373           2 : static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1(
     374             :         TALLOC_CTX *mem_ctx)
     375             : {
     376           0 :         struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1;
     377           0 :         struct dom_usr *dom_users;
     378           0 :         const char *pwd_server;
     379           0 :         char *pwd_tmp;
     380           0 :         int i, num_dom_users, ret;
     381             : 
     382           2 :         ctr1 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr1);
     383           2 :         if (ctr1 == NULL) {
     384           0 :                 return NULL;
     385             :         }
     386             : 
     387           2 :         ret = get_domain_userlist(talloc_tos(), &dom_users);
     388           2 :         if (ret != 0) {
     389           0 :                 TALLOC_FREE(ctr1);
     390           0 :                 errno = ret;
     391           0 :                 return NULL;
     392             :         }
     393           2 :         num_dom_users = talloc_array_length(dom_users);
     394             : 
     395           2 :         ctr1->user1 = talloc_array(ctr1, struct wkssvc_NetrWkstaUserInfo1,
     396             :                                    num_dom_users);
     397           2 :         if (ctr1->user1 == NULL) {
     398           0 :                 TALLOC_FREE(ctr1);
     399           0 :                 TALLOC_FREE(dom_users);
     400           0 :                 errno = ENOMEM;
     401           0 :                 return NULL;
     402             :         }
     403             : 
     404           2 :         pwd_server = "";
     405             : 
     406           2 :         if ((pwd_tmp = talloc_strdup(ctr1->user1, lp_password_server()))) {
     407             :                 /* The configured password server is a full DNS name but
     408             :                  * for the logon server we need to return just the first
     409             :                  * component (machine name) of it in upper-case */
     410           2 :                 char *p = strchr(pwd_tmp, '.');
     411           2 :                 if (p) {
     412           0 :                         *p = '\0';
     413             :                 } else {
     414           2 :                         p = pwd_tmp + strlen(pwd_tmp);
     415             :                 }
     416          10 :                 while (--p >= pwd_tmp) {
     417           8 :                         *p = toupper(*p);
     418             :                 }
     419           2 :                 pwd_server = pwd_tmp;
     420             :         }
     421             : 
     422             :         /* Now domain users */
     423           2 :         for (i=0; i<num_dom_users; i++) {
     424           0 :                 ctr1->user1[i].user_name =
     425           0 :                                 talloc_strdup(ctr1->user1, dom_users[i].name);
     426           0 :                 ctr1->user1[i].logon_domain =
     427           0 :                                 talloc_strdup(ctr1->user1, dom_users[i].domain);
     428           0 :                 ctr1->user1[i].logon_server = pwd_server;
     429             : 
     430           0 :                 ctr1->user1[i++].other_domains = NULL;       /* Maybe in future? */
     431             :         }
     432             : 
     433           2 :         ctr1->entries_read = i;
     434             : 
     435           2 :         TALLOC_FREE(dom_users);
     436           2 :         return ctr1;
     437             : }
     438             : 
     439             : /********************************************************************
     440             :  Handling for RPC Workstation Service request NetWkstaEnumUsers
     441             :  (a.k.a Windows NetWkstaUserEnum)
     442             :  ********************************************************************/
     443             : 
     444           4 : WERROR _wkssvc_NetWkstaEnumUsers(struct pipes_struct *p,
     445             :                                  struct wkssvc_NetWkstaEnumUsers *r)
     446             : {
     447           4 :         struct dcesrv_call_state *dce_call = p->dce_call;
     448           0 :         struct auth_session_info *session_info =
     449           4 :                 dcesrv_call_session_info(dce_call);
     450             : 
     451             :         /* This with any level should only be allowed from a domain administrator */
     452           4 :         if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
     453           4 :                                 session_info->security_token)) {
     454           0 :                 struct dom_sid_buf buf;
     455           0 :                 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
     456           0 :                 DEBUGADD(3,(" - does not have sid for Administrators group "
     457             :                             "%s\n",
     458             :                             dom_sid_str_buf(
     459             :                                     &global_sid_Builtin_Administrators,
     460             :                                     &buf)));
     461           0 :                 security_token_debug(
     462           0 :                         DBGC_CLASS, 3, session_info->security_token);
     463           0 :                 return WERR_ACCESS_DENIED;
     464             :         }
     465             : 
     466           4 :         switch (r->in.info->level) {
     467           2 :         case 0:
     468           2 :                 r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx);
     469           2 :                 if (r->out.info->ctr.user0 == NULL) {
     470           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     471             :                 }
     472           2 :                 r->out.info->level = r->in.info->level;
     473           2 :                 *r->out.entries_read = r->out.info->ctr.user0->entries_read;
     474           2 :                 if (r->out.resume_handle != NULL) {
     475           2 :                         *r->out.resume_handle = 0;
     476             :                 }
     477           2 :                 break;
     478           2 :         case 1:
     479           2 :                 r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx);
     480           2 :                 if (r->out.info->ctr.user1 == NULL) {
     481           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     482             :                 }
     483           2 :                 r->out.info->level = r->in.info->level;
     484           2 :                 *r->out.entries_read = r->out.info->ctr.user1->entries_read;
     485           2 :                 if (r->out.resume_handle != NULL) {
     486           2 :                         *r->out.resume_handle = 0;
     487             :                 }
     488           2 :                 break;
     489           0 :         default:
     490           0 :                 return WERR_INVALID_LEVEL;
     491             :         }
     492             : 
     493           4 :         return WERR_OK;
     494             : }
     495             : 
     496             : /********************************************************************
     497             :  ********************************************************************/
     498             : 
     499           2 : WERROR _wkssvc_NetrWkstaUserGetInfo(struct pipes_struct *p,
     500             :                                     struct wkssvc_NetrWkstaUserGetInfo *r)
     501             : {
     502             :         /* FIXME: Add implementation code here */
     503           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     504           2 :         return WERR_NOT_SUPPORTED;
     505             : }
     506             : 
     507             : /********************************************************************
     508             :  ********************************************************************/
     509             : 
     510           0 : WERROR _wkssvc_NetrWkstaUserSetInfo(struct pipes_struct *p,
     511             :                                     struct wkssvc_NetrWkstaUserSetInfo *r)
     512             : {
     513             :         /* FIXME: Add implementation code here */
     514           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     515           0 :         return WERR_NOT_SUPPORTED;
     516             : }
     517             : 
     518             : /********************************************************************
     519             :  ********************************************************************/
     520             : 
     521           2 : WERROR _wkssvc_NetWkstaTransportEnum(struct pipes_struct *p,
     522             :                                      struct wkssvc_NetWkstaTransportEnum *r)
     523             : {
     524             :         /* FIXME: Add implementation code here */
     525           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     526           2 :         return WERR_NOT_SUPPORTED;
     527             : }
     528             : 
     529             : /********************************************************************
     530             :  ********************************************************************/
     531             : 
     532           2 : WERROR _wkssvc_NetrWkstaTransportAdd(struct pipes_struct *p,
     533             :                                      struct wkssvc_NetrWkstaTransportAdd *r)
     534             : {
     535             :         /* FIXME: Add implementation code here */
     536           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     537           2 :         return WERR_NOT_SUPPORTED;
     538             : }
     539             : 
     540             : /********************************************************************
     541             :  ********************************************************************/
     542             : 
     543           2 : WERROR _wkssvc_NetrWkstaTransportDel(struct pipes_struct *p,
     544             :                                      struct wkssvc_NetrWkstaTransportDel *r)
     545             : {
     546             :         /* FIXME: Add implementation code here */
     547           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     548           2 :         return WERR_NOT_SUPPORTED;
     549             : }
     550             : 
     551             : /********************************************************************
     552             :  ********************************************************************/
     553             : 
     554           2 : WERROR _wkssvc_NetrUseAdd(struct pipes_struct *p,
     555             :                           struct wkssvc_NetrUseAdd *r)
     556             : {
     557             :         /* FIXME: Add implementation code here */
     558           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     559           2 :         return WERR_NOT_SUPPORTED;
     560             : }
     561             : 
     562             : /********************************************************************
     563             :  ********************************************************************/
     564             : 
     565           0 : WERROR _wkssvc_NetrUseGetInfo(struct pipes_struct *p,
     566             :                               struct wkssvc_NetrUseGetInfo *r)
     567             : {
     568             :         /* FIXME: Add implementation code here */
     569           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     570           0 :         return WERR_NOT_SUPPORTED;
     571             : }
     572             : 
     573             : /********************************************************************
     574             :  ********************************************************************/
     575             : 
     576           2 : WERROR _wkssvc_NetrUseDel(struct pipes_struct *p,
     577             :                           struct wkssvc_NetrUseDel *r)
     578             : {
     579             :         /* FIXME: Add implementation code here */
     580           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     581           2 :         return WERR_NOT_SUPPORTED;
     582             : }
     583             : 
     584             : /********************************************************************
     585             :  ********************************************************************/
     586             : 
     587           4 : WERROR _wkssvc_NetrUseEnum(struct pipes_struct *p,
     588             :                            struct wkssvc_NetrUseEnum *r)
     589             : {
     590             :         /* FIXME: Add implementation code here */
     591           4 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     592           4 :         return WERR_NOT_SUPPORTED;
     593             : }
     594             : 
     595             : /********************************************************************
     596             :  ********************************************************************/
     597             : 
     598           2 : WERROR _wkssvc_NetrMessageBufferSend(struct pipes_struct *p,
     599             :                                      struct wkssvc_NetrMessageBufferSend *r)
     600             : {
     601             :         /* FIXME: Add implementation code here */
     602           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     603           2 :         return WERR_NOT_SUPPORTED;
     604             : }
     605             : 
     606             : /********************************************************************
     607             :  ********************************************************************/
     608             : 
     609           2 : WERROR _wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct *p,
     610             :                                             struct wkssvc_NetrWorkstationStatisticsGet *r)
     611             : {
     612             :         /* FIXME: Add implementation code here */
     613           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     614           2 :         return WERR_NOT_SUPPORTED;
     615             : }
     616             : 
     617             : /********************************************************************
     618             :  ********************************************************************/
     619             : 
     620           2 : WERROR _wkssvc_NetrLogonDomainNameAdd(struct pipes_struct *p,
     621             :                                       struct wkssvc_NetrLogonDomainNameAdd *r)
     622             : {
     623             :         /* FIXME: Add implementation code here */
     624           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     625           2 :         return WERR_NOT_SUPPORTED;
     626             : }
     627             : 
     628             : /********************************************************************
     629             :  ********************************************************************/
     630             : 
     631           2 : WERROR _wkssvc_NetrLogonDomainNameDel(struct pipes_struct *p,
     632             :                                       struct wkssvc_NetrLogonDomainNameDel *r)
     633             : {
     634             :         /* FIXME: Add implementation code here */
     635           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     636           2 :         return WERR_NOT_SUPPORTED;
     637             : }
     638             : 
     639             : /********************************************************************
     640             :  ********************************************************************/
     641             : 
     642           2 : WERROR _wkssvc_NetrJoinDomain(struct pipes_struct *p,
     643             :                               struct wkssvc_NetrJoinDomain *r)
     644             : {
     645             :         /* FIXME: Add implementation code here */
     646           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     647           2 :         return WERR_NOT_SUPPORTED;
     648             : }
     649             : 
     650             : /********************************************************************
     651             :  ********************************************************************/
     652             : 
     653           2 : WERROR _wkssvc_NetrUnjoinDomain(struct pipes_struct *p,
     654             :                                 struct wkssvc_NetrUnjoinDomain *r)
     655             : {
     656             :         /* FIXME: Add implementation code here */
     657           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     658           2 :         return WERR_NOT_SUPPORTED;
     659             : }
     660             : 
     661             : /********************************************************************
     662             :  ********************************************************************/
     663             : 
     664           0 : WERROR _wkssvc_NetrRenameMachineInDomain(struct pipes_struct *p,
     665             :                                          struct wkssvc_NetrRenameMachineInDomain *r)
     666             : {
     667             :         /* FIXME: Add implementation code here */
     668           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     669           0 :         return WERR_NOT_SUPPORTED;
     670             : }
     671             : 
     672             : /********************************************************************
     673             :  ********************************************************************/
     674             : 
     675           2 : WERROR _wkssvc_NetrValidateName(struct pipes_struct *p,
     676             :                                 struct wkssvc_NetrValidateName *r)
     677             : {
     678             :         /* FIXME: Add implementation code here */
     679           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     680           2 :         return WERR_NOT_SUPPORTED;
     681             : }
     682             : 
     683             : /********************************************************************
     684             :  ********************************************************************/
     685             : 
     686           2 : WERROR _wkssvc_NetrGetJoinInformation(struct pipes_struct *p,
     687             :                                       struct wkssvc_NetrGetJoinInformation *r)
     688             : {
     689             :         /* FIXME: Add implementation code here */
     690           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     691           2 :         return WERR_NOT_SUPPORTED;
     692             : }
     693             : 
     694             : /********************************************************************
     695             :  ********************************************************************/
     696             : 
     697           2 : WERROR _wkssvc_NetrGetJoinableOus(struct pipes_struct *p,
     698             :                                   struct wkssvc_NetrGetJoinableOus *r)
     699             : {
     700             :         /* FIXME: Add implementation code here */
     701           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     702           2 :         return WERR_NOT_SUPPORTED;
     703             : }
     704             : 
     705             : /********************************************************************
     706             :  _wkssvc_NetrJoinDomain2
     707             :  ********************************************************************/
     708             : 
     709           0 : WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
     710             :                                struct wkssvc_NetrJoinDomain2 *r)
     711             : {
     712           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
     713           0 :         struct auth_session_info *session_info =
     714           0 :                 dcesrv_call_session_info(dce_call);
     715           0 :         struct libnet_JoinCtx *j = NULL;
     716           0 :         char *cleartext_pwd = NULL;
     717           0 :         char *admin_domain = NULL;
     718           0 :         char *admin_account = NULL;
     719           0 :         WERROR werr;
     720           0 :         struct security_token *token = session_info->security_token;
     721           0 :         NTSTATUS status;
     722           0 :         DATA_BLOB session_key;
     723           0 :         bool ok;
     724             : 
     725           0 :         if (!r->in.domain_name) {
     726           0 :                 return WERR_INVALID_PARAMETER;
     727             :         }
     728             : 
     729           0 :         if (!r->in.admin_account || !r->in.encrypted_password) {
     730           0 :                 return WERR_INVALID_PARAMETER;
     731             :         }
     732             : 
     733           0 :         if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
     734           0 :             !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
     735           0 :             !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
     736           0 :                 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
     737             :                         "sufficient privileges\n"));
     738           0 :                 return WERR_ACCESS_DENIED;
     739             :         }
     740             : 
     741           0 :         if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED) ||
     742           0 :             (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
     743           0 :                 return WERR_NOT_SUPPORTED;
     744             :         }
     745             : 
     746           0 :         status = session_extract_session_key(session_info,
     747             :                                              &session_key,
     748             :                                              KEY_USE_16BYTES);
     749           0 :         if(!NT_STATUS_IS_OK(status)) {
     750           0 :                 DEBUG(5,("_wkssvc_NetrJoinDomain2: no session key %s\n",
     751             :                         nt_errstr(status)));
     752           0 :                 return WERR_NO_USER_SESSION_KEY;
     753             :         }
     754             : 
     755           0 :         werr = decode_wkssvc_join_password_buffer(
     756             :                 p->mem_ctx, r->in.encrypted_password,
     757             :                 &session_key, &cleartext_pwd);
     758           0 :         if (!W_ERROR_IS_OK(werr)) {
     759           0 :                 return werr;
     760             :         }
     761             : 
     762           0 :         ok = split_domain_user(p->mem_ctx,
     763             :                                r->in.admin_account,
     764             :                                &admin_domain,
     765             :                                &admin_account);
     766           0 :         if (!ok) {
     767           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     768             :         }
     769             : 
     770           0 :         werr = libnet_init_JoinCtx(p->mem_ctx, &j);
     771           0 :         if (!W_ERROR_IS_OK(werr)) {
     772           0 :                 return werr;
     773             :         }
     774             : 
     775           0 :         j->in.domain_name    = r->in.domain_name;
     776           0 :         j->in.account_ou     = r->in.account_ou;
     777           0 :         j->in.join_flags     = r->in.join_flags;
     778           0 :         j->in.admin_account  = admin_account;
     779           0 :         j->in.admin_password = cleartext_pwd;
     780           0 :         j->in.debug          = true;
     781           0 :         j->in.modify_config     = lp_config_backend_is_registry();
     782           0 :         j->in.msg_ctx                = p->msg_ctx;
     783             : 
     784           0 :         become_root();
     785           0 :         setenv(KRB5_ENV_CCNAME, "MEMORY:_wkssvc_NetrJoinDomain2", 1);
     786           0 :         werr = libnet_Join(p->mem_ctx, j);
     787           0 :         unsetenv(KRB5_ENV_CCNAME);
     788           0 :         unbecome_root();
     789             : 
     790           0 :         if (!W_ERROR_IS_OK(werr)) {
     791           0 :                 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
     792             :                         j->out.error_string ? j->out.error_string :
     793             :                         win_errstr(werr)));
     794             :         }
     795             : 
     796           0 :         TALLOC_FREE(j);
     797           0 :         return werr;
     798             : }
     799             : 
     800             : /********************************************************************
     801             :  _wkssvc_NetrUnjoinDomain2
     802             :  ********************************************************************/
     803             : 
     804           0 : WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
     805             :                                  struct wkssvc_NetrUnjoinDomain2 *r)
     806             : {
     807           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
     808           0 :         struct auth_session_info *session_info =
     809           0 :                 dcesrv_call_session_info(dce_call);
     810           0 :         struct libnet_UnjoinCtx *u = NULL;
     811           0 :         char *cleartext_pwd = NULL;
     812           0 :         char *admin_domain = NULL;
     813           0 :         char *admin_account = NULL;
     814           0 :         WERROR werr;
     815           0 :         struct security_token *token = session_info->security_token;
     816           0 :         NTSTATUS status;
     817           0 :         DATA_BLOB session_key;
     818           0 :         bool ok;
     819             : 
     820           0 :         if (!r->in.account || !r->in.encrypted_password) {
     821           0 :                 return WERR_INVALID_PARAMETER;
     822             :         }
     823             : 
     824           0 :         if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
     825           0 :             !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
     826           0 :             !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
     827           0 :                 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
     828             :                         "sufficient privileges\n"));
     829           0 :                 return WERR_ACCESS_DENIED;
     830             :         }
     831             : 
     832           0 :         status = session_extract_session_key(session_info,
     833             :                                              &session_key,
     834             :                                              KEY_USE_16BYTES);
     835           0 :         if (!NT_STATUS_IS_OK(status)) {
     836           0 :                 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: no session key %s\n",
     837             :                         nt_errstr(status)));
     838           0 :                 return WERR_NO_USER_SESSION_KEY;
     839             :         }
     840             : 
     841           0 :         werr = decode_wkssvc_join_password_buffer(
     842             :                 p->mem_ctx, r->in.encrypted_password,
     843             :                 &session_key, &cleartext_pwd);
     844           0 :         if (!W_ERROR_IS_OK(werr)) {
     845           0 :                 return werr;
     846             :         }
     847             : 
     848           0 :         ok = split_domain_user(p->mem_ctx,
     849             :                                r->in.account,
     850             :                                &admin_domain,
     851             :                                &admin_account);
     852           0 :         if (!ok) {
     853           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     854             :         }
     855             : 
     856           0 :         werr = libnet_init_UnjoinCtx(p->mem_ctx, &u);
     857           0 :         if (!W_ERROR_IS_OK(werr)) {
     858           0 :                 return werr;
     859             :         }
     860             : 
     861           0 :         u->in.domain_name    = lp_realm();
     862           0 :         u->in.unjoin_flags   = r->in.unjoin_flags |
     863             :                                   WKSSVC_JOIN_FLAGS_JOIN_TYPE;
     864           0 :         u->in.admin_account  = admin_account;
     865           0 :         u->in.admin_password = cleartext_pwd;
     866           0 :         u->in.debug          = true;
     867           0 :         u->in.modify_config     = lp_config_backend_is_registry();
     868           0 :         u->in.msg_ctx                = p->msg_ctx;
     869             : 
     870           0 :         become_root();
     871           0 :         setenv(KRB5_ENV_CCNAME, "MEMORY:_wkssvc_NetrUnjoinDomain2", 1);
     872           0 :         werr = libnet_Unjoin(p->mem_ctx, u);
     873           0 :         unsetenv(KRB5_ENV_CCNAME);
     874           0 :         unbecome_root();
     875             : 
     876           0 :         if (!W_ERROR_IS_OK(werr)) {
     877           0 :                 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
     878             :                         u->out.error_string ? u->out.error_string :
     879             :                         win_errstr(werr)));
     880             :         }
     881             : 
     882           0 :         TALLOC_FREE(u);
     883           0 :         return werr;
     884             : }
     885             : 
     886             : /********************************************************************
     887             :  ********************************************************************/
     888             : 
     889           0 : WERROR _wkssvc_NetrRenameMachineInDomain2(struct pipes_struct *p,
     890             :                                           struct wkssvc_NetrRenameMachineInDomain2 *r)
     891             : {
     892             :         /* for now just return not supported */
     893           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     894           0 :         return WERR_NOT_SUPPORTED;
     895             : }
     896             : 
     897             : /********************************************************************
     898             :  ********************************************************************/
     899             : 
     900           2 : WERROR _wkssvc_NetrValidateName2(struct pipes_struct *p,
     901             :                                  struct wkssvc_NetrValidateName2 *r)
     902             : {
     903             :         /* FIXME: Add implementation code here */
     904           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     905           2 :         return WERR_NOT_SUPPORTED;
     906             : }
     907             : 
     908             : /********************************************************************
     909             :  ********************************************************************/
     910             : 
     911           2 : WERROR _wkssvc_NetrGetJoinableOus2(struct pipes_struct *p,
     912             :                                    struct wkssvc_NetrGetJoinableOus2 *r)
     913             : {
     914             :         /* FIXME: Add implementation code here */
     915           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     916           2 :         return WERR_NOT_SUPPORTED;
     917             : }
     918             : 
     919             : /********************************************************************
     920             :  ********************************************************************/
     921             : 
     922           2 : WERROR _wkssvc_NetrAddAlternateComputerName(struct pipes_struct *p,
     923             :                                             struct wkssvc_NetrAddAlternateComputerName *r)
     924             : {
     925             :         /* FIXME: Add implementation code here */
     926           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     927           2 :         return WERR_NOT_SUPPORTED;
     928             : }
     929             : 
     930             : /********************************************************************
     931             :  ********************************************************************/
     932             : 
     933           2 : WERROR _wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct *p,
     934             :                                                struct wkssvc_NetrRemoveAlternateComputerName *r)
     935             : {
     936             :         /* FIXME: Add implementation code here */
     937           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     938           2 :         return WERR_NOT_SUPPORTED;
     939             : }
     940             : 
     941             : /********************************************************************
     942             :  ********************************************************************/
     943             : 
     944           0 : WERROR _wkssvc_NetrSetPrimaryComputername(struct pipes_struct *p,
     945             :                                           struct wkssvc_NetrSetPrimaryComputername *r)
     946             : {
     947             :         /* FIXME: Add implementation code here */
     948           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     949           0 :         return WERR_NOT_SUPPORTED;
     950             : }
     951             : 
     952             : /********************************************************************
     953             :  ********************************************************************/
     954             : 
     955           2 : WERROR _wkssvc_NetrEnumerateComputerNames(struct pipes_struct *p,
     956             :                                           struct wkssvc_NetrEnumerateComputerNames *r)
     957             : {
     958             :         /* FIXME: Add implementation code here */
     959           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     960           2 :         return WERR_NOT_SUPPORTED;
     961             : }
     962             : 
     963             : /* include the generated boilerplate */
     964             : #include "librpc/gen_ndr/ndr_wkssvc_scompat.c"

Generated by: LCOV version 1.14