rpc_client/cli_netlogon.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    NT Domain Authentication SMB / MSRPC client
00004    Copyright (C) Andrew Tridgell 1992-2000
00005    Copyright (C) Jeremy Allison                    1998.
00006    Largely re-written by Jeremy Allison (C)        2005.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 #include "includes.h"
00024 
00025 /* LSA Request Challenge. Sends our challenge to server, then gets
00026    server response. These are used to generate the credentials.
00027  The sent and received challenges are stored in the netlog pipe
00028  private data. Only call this via rpccli_netlogon_setup_creds(). JRA.
00029 */
00030 
00031 static NTSTATUS rpccli_net_req_chal(struct rpc_pipe_client *cli,
00032                                 TALLOC_CTX *mem_ctx,
00033                                 const char *server_name,
00034                                 const char *clnt_name,
00035                                 const DOM_CHAL *clnt_chal_in,
00036                                 DOM_CHAL *srv_chal_out)
00037 {
00038         prs_struct qbuf, rbuf;
00039         NET_Q_REQ_CHAL q;
00040         NET_R_REQ_CHAL r;
00041         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00042 
00043         /* create and send a MSRPC command with api NET_REQCHAL */
00044 
00045         DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n",
00046                 clnt_name, server_name));
00047         
00048         /* store the parameters */
00049         init_q_req_chal(&q, server_name, clnt_name, clnt_chal_in);
00050 
00051         /* Marshall data and send request */
00052         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_REQCHAL,
00053                 q, r,
00054                 qbuf, rbuf,
00055                 net_io_q_req_chal,
00056                 net_io_r_req_chal,
00057                 NT_STATUS_UNSUCCESSFUL);
00058 
00059         result = r.status;
00060 
00061         /* Return result */
00062 
00063         if (NT_STATUS_IS_OK(result)) {
00064                 /* Store the returned server challenge. */
00065                 *srv_chal_out = r.srv_chal;
00066         }
00067 
00068         return result;
00069 }
00070 
00071 #if 0
00072 /****************************************************************************
00073 LSA Authenticate 2
00074 
00075 Send the client credential, receive back a server credential.
00076 Ensure that the server credential returned matches the session key 
00077 encrypt of the server challenge originally received. JRA.
00078 ****************************************************************************/
00079 
00080   NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, 
00081                        uint16 sec_chan, 
00082                        uint32 *neg_flags, DOM_CHAL *srv_chal)
00083 {
00084         prs_struct qbuf, rbuf;
00085         NET_Q_AUTH_2 q;
00086         NET_R_AUTH_2 r;
00087         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00088         fstring machine_acct;
00089 
00090         if ( sec_chan == SEC_CHAN_DOMAIN )
00091                 fstr_sprintf( machine_acct, "%s$", lp_workgroup() );
00092         else
00093                 fstrcpy( machine_acct, cli->mach_acct );
00094         
00095         /* create and send a MSRPC command with api NET_AUTH2 */
00096 
00097         DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
00098                  cli->srv_name_slash, machine_acct, sec_chan, global_myname(),
00099                  credstr(cli->clnt_cred.challenge.data), *neg_flags));
00100 
00101         /* store the parameters */
00102 
00103         init_q_auth_2(&q, cli->srv_name_slash, machine_acct, 
00104                       sec_chan, global_myname(), &cli->clnt_cred.challenge, 
00105                       *neg_flags);
00106 
00107         /* turn parameters into data stream */
00108 
00109         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
00110                 q, r,
00111                 qbuf, rbuf,
00112                 net_io_q_auth_2,
00113                 net_io_r_auth_2,
00114                 NT_STATUS_UNSUCCESSFUL);
00115 
00116         result = r.status;
00117 
00118         if (NT_STATUS_IS_OK(result)) {
00119                 UTIME zerotime;
00120                 
00121                 /*
00122                  * Check the returned value using the initial
00123                  * server received challenge.
00124                  */
00125 
00126                 zerotime.time = 0;
00127                 if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
00128 
00129                         /*
00130                          * Server replied with bad credential. Fail.
00131                          */
00132                         DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
00133 password ?).\n", cli->cli->desthost ));
00134                         return NT_STATUS_ACCESS_DENIED;
00135                 }
00136                 *neg_flags = r.srv_flgs.neg_flags;
00137         }
00138 
00139         return result;
00140 }
00141 #endif
00142 
00143 /****************************************************************************
00144  LSA Authenticate 2
00145 
00146  Send the client credential, receive back a server credential.
00147  The caller *must* ensure that the server credential returned matches the session key 
00148  encrypt of the server challenge originally received. JRA.
00149 ****************************************************************************/
00150 
00151 static NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
00152                         TALLOC_CTX *mem_ctx,
00153                         const char *server_name,
00154                         const char *account_name,
00155                         uint16 sec_chan_type,
00156                         const char *computer_name,
00157                         uint32 *neg_flags_inout,
00158                         const DOM_CHAL *clnt_chal_in,
00159                         DOM_CHAL *srv_chal_out)
00160 {
00161         prs_struct qbuf, rbuf;
00162         NET_Q_AUTH_2 q;
00163         NET_R_AUTH_2 r;
00164         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00165 
00166         /* create and send a MSRPC command with api NET_AUTH2 */
00167 
00168         DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n",
00169                  server_name, account_name, sec_chan_type, computer_name,
00170                  *neg_flags_inout));
00171 
00172         /* store the parameters */
00173 
00174         init_q_auth_2(&q, server_name, account_name, sec_chan_type,
00175                       computer_name, clnt_chal_in, *neg_flags_inout);
00176 
00177         /* turn parameters into data stream */
00178 
00179         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
00180                 q, r,
00181                 qbuf, rbuf,
00182                 net_io_q_auth_2,
00183                 net_io_r_auth_2,
00184                 NT_STATUS_UNSUCCESSFUL);
00185 
00186         result = r.status;
00187 
00188         *neg_flags_inout = r.srv_flgs.neg_flags;
00189 
00190         if (NT_STATUS_IS_OK(result)) {
00191                 *srv_chal_out = r.srv_chal;
00192         }
00193 
00194         return result;
00195 }
00196 
00197 #if 0   /* not currebntly used */
00198 /****************************************************************************
00199  LSA Authenticate 3
00200 
00201  Send the client credential, receive back a server credential.
00202  The caller *must* ensure that the server credential returned matches the session key 
00203  encrypt of the server challenge originally received. JRA.
00204 ****************************************************************************/
00205 
00206 static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli, 
00207                         TALLOC_CTX *mem_ctx,
00208                         const char *server_name,
00209                         const char *account_name,
00210                         uint16 sec_chan_type,
00211                         const char *computer_name,
00212                         uint32 *neg_flags_inout,
00213                         const DOM_CHAL *clnt_chal_in,
00214                         DOM_CHAL *srv_chal_out)
00215 {
00216         prs_struct qbuf, rbuf;
00217         NET_Q_AUTH_3 q;
00218         NET_R_AUTH_3 r;
00219         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00220 
00221         /* create and send a MSRPC command with api NET_AUTH2 */
00222 
00223         DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
00224                 server_name, account_name, sec_chan_type, computer_name,
00225                 credstr(clnt_chal_in->data), *neg_flags_inout));
00226 
00227         /* store the parameters */
00228         init_q_auth_3(&q, server_name, account_name, sec_chan_type,
00229                         computer_name, clnt_chal_in, *neg_flags_inout);
00230 
00231         /* turn parameters into data stream */
00232 
00233         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH3,
00234                 q, r,
00235                 qbuf, rbuf,
00236                 net_io_q_auth_3,
00237                 net_io_r_auth_3,
00238                 NT_STATUS_UNSUCCESSFUL);
00239 
00240         if (NT_STATUS_IS_OK(result)) {
00241                 *srv_chal_out = r.srv_chal;
00242                 *neg_flags_inout = r.srv_flgs.neg_flags;
00243         }
00244 
00245         return result;
00246 }
00247 #endif  /* not currebntly used */
00248 
00249 /****************************************************************************
00250  Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
00251  credentials chain. Stores the credentials in the struct dcinfo in the
00252  netlogon pipe struct.
00253 ****************************************************************************/
00254 
00255 NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
00256                                 const char *server_name,
00257                                 const char *domain,
00258                                 const char *clnt_name,
00259                                 const char *machine_account,
00260                                 const unsigned char machine_pwd[16],
00261                                 uint32 sec_chan_type,
00262                                 uint32 *neg_flags_inout)
00263 {
00264         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00265         DOM_CHAL clnt_chal_send;
00266         DOM_CHAL srv_chal_recv;
00267         struct dcinfo *dc;
00268         bool retried = false;
00269 
00270         SMB_ASSERT(cli->pipe_idx == PI_NETLOGON);
00271 
00272         dc = cli->dc;
00273         if (!dc) {
00274                 return NT_STATUS_INVALID_PARAMETER;
00275         }
00276 
00277         /* Ensure we don't reuse any of this state. */
00278         ZERO_STRUCTP(dc);
00279 
00280         /* Store the machine account password we're going to use. */
00281         memcpy(dc->mach_pw, machine_pwd, 16);
00282 
00283         fstrcpy(dc->remote_machine, "\\\\");
00284         fstrcat(dc->remote_machine, server_name);
00285 
00286         fstrcpy(dc->domain, domain);
00287 
00288         fstr_sprintf( dc->mach_acct, "%s$", machine_account);
00289 
00290  again:
00291         /* Create the client challenge. */
00292         generate_random_buffer(clnt_chal_send.data, 8);
00293 
00294         /* Get the server challenge. */
00295         result = rpccli_net_req_chal(cli,
00296                                 cli->mem_ctx,
00297                                 dc->remote_machine,
00298                                 clnt_name,
00299                                 &clnt_chal_send,
00300                                 &srv_chal_recv);
00301 
00302         if (!NT_STATUS_IS_OK(result)) {
00303                 return result;
00304         }
00305 
00306         /* Calculate the session key and client credentials */
00307         creds_client_init(*neg_flags_inout,
00308                         dc,
00309                         &clnt_chal_send,
00310                         &srv_chal_recv,
00311                         machine_pwd,
00312                         &clnt_chal_send);
00313 
00314         /*  
00315          * Send client auth-2 challenge and receive server repy.
00316          */
00317 
00318         result = rpccli_net_auth2(cli,
00319                         cli->mem_ctx,
00320                         dc->remote_machine,
00321                         dc->mach_acct,
00322                         sec_chan_type,
00323                         clnt_name,
00324                         neg_flags_inout,
00325                         &clnt_chal_send, /* input. */
00326                         &srv_chal_recv); /* output */
00327 
00328         /* we might be talking to NT4, so let's downgrade in that case and retry
00329          * with the returned neg_flags - gd */
00330 
00331         if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) && !retried) {
00332                 retried = true;
00333                 goto again;
00334         }
00335 
00336         if (!NT_STATUS_IS_OK(result)) {
00337                 return result;
00338         }
00339 
00340         /*
00341          * Check the returned value using the initial
00342          * server received challenge.
00343          */
00344 
00345         if (!creds_client_check(dc, &srv_chal_recv)) {
00346                 /*
00347                  * Server replied with bad credential. Fail.
00348                  */
00349                 DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
00350                         "replied with bad credential\n",
00351                         cli->cli->desthost ));
00352                 return NT_STATUS_ACCESS_DENIED;
00353         }
00354 
00355         DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
00356                 "chain established.\n",
00357                 cli->cli->desthost ));
00358 
00359         return NT_STATUS_OK;
00360 }
00361 
00362 /* Logon Control 2 */
00363 
00364 NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00365                                   uint32 query_level)
00366 {
00367         prs_struct qbuf, rbuf;
00368         NET_Q_LOGON_CTRL2 q;
00369         NET_R_LOGON_CTRL2 r;
00370         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00371         fstring server;
00372 
00373         ZERO_STRUCT(q);
00374         ZERO_STRUCT(r);
00375 
00376         /* Initialise input parameters */
00377 
00378         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
00379         init_net_q_logon_ctrl2(&q, server, query_level);
00380 
00381         /* Marshall data and send request */
00382 
00383         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2,
00384                 q, r,
00385                 qbuf, rbuf,
00386                 net_io_q_logon_ctrl2,
00387                 net_io_r_logon_ctrl2,
00388                 NT_STATUS_UNSUCCESSFUL);
00389 
00390         result = r.status;
00391         return result;
00392 }
00393 
00394 /* GetAnyDCName */
00395 
00396 WERROR rpccli_netlogon_getanydcname(struct rpc_pipe_client *cli,
00397                                     TALLOC_CTX *mem_ctx, const char *mydcname,
00398                                     const char *domainname, fstring newdcname)
00399 {
00400         prs_struct qbuf, rbuf;
00401         NET_Q_GETANYDCNAME q;
00402         NET_R_GETANYDCNAME r;
00403         WERROR result;
00404         fstring mydcname_slash;
00405 
00406         ZERO_STRUCT(q);
00407         ZERO_STRUCT(r);
00408 
00409         /* Initialise input parameters */
00410 
00411         slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname);
00412         init_net_q_getanydcname(&q, mydcname_slash, domainname);
00413 
00414         /* Marshall data and send request */
00415 
00416         CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETANYDCNAME,
00417                 q, r,
00418                 qbuf, rbuf,
00419                 net_io_q_getanydcname,
00420                 net_io_r_getanydcname,
00421                 WERR_GENERAL_FAILURE);
00422 
00423         result = r.status;
00424 
00425         if (W_ERROR_IS_OK(result)) {
00426                 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
00427         }
00428 
00429         return result;
00430 }
00431 
00432 static WERROR pull_domain_controller_info_from_getdcname_reply(TALLOC_CTX *mem_ctx,
00433                                                                struct DS_DOMAIN_CONTROLLER_INFO **info_out, 
00434                                                                NET_R_DSR_GETDCNAME *r)
00435 {
00436         struct DS_DOMAIN_CONTROLLER_INFO *info;
00437 
00438         info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO);
00439         if (!info) {
00440                 return WERR_NOMEM;
00441         }
00442 
00443         if (&r->uni_dc_unc) {
00444 
00445                 char *tmp;
00446                 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_unc);
00447                 if (tmp == NULL) {
00448                         return WERR_GENERAL_FAILURE;
00449                 }
00450                 if (*tmp == '\\') tmp += 1;
00451                 if (*tmp == '\\') tmp += 1;
00452 
00453                 info->domain_controller_name = talloc_strdup(mem_ctx, tmp);
00454                 if (info->domain_controller_name == NULL) {
00455                         return WERR_GENERAL_FAILURE;
00456                 }
00457         }
00458 
00459         if (&r->uni_dc_address) {
00460 
00461                 char *tmp;
00462                 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_address);
00463                 if (tmp == NULL) {
00464                         return WERR_GENERAL_FAILURE;
00465                 }
00466                 if (*tmp == '\\') tmp += 1;
00467                 if (*tmp == '\\') tmp += 1;
00468 
00469                 info->domain_controller_address = talloc_strdup(mem_ctx, tmp);
00470                 if (info->domain_controller_address == NULL) {
00471                         return WERR_GENERAL_FAILURE;
00472                 }
00473         }
00474 
00475         info->domain_controller_address_type = r->dc_address_type;
00476 
00477         info->domain_guid = talloc_memdup(mem_ctx, &r->domain_guid, sizeof(struct GUID));
00478         if (!info->domain_guid) {
00479                 return WERR_GENERAL_FAILURE;
00480         }
00481 
00482         if (&r->uni_domain_name) {
00483                 info->domain_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_domain_name);
00484                 if (!info->domain_name) {
00485                         return WERR_GENERAL_FAILURE;
00486                 }
00487         }
00488 
00489         if (&r->uni_forest_name) {
00490                 info->dns_forest_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_forest_name);
00491                 if (!info->dns_forest_name) {
00492                         return WERR_GENERAL_FAILURE;
00493                 }
00494         }
00495 
00496         info->flags = r->dc_flags;
00497 
00498         if (&r->uni_dc_site_name) {
00499                 info->dc_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_site_name);
00500                 if (!info->dc_site_name) {
00501                         return WERR_GENERAL_FAILURE;
00502                 }
00503         }
00504 
00505         if (&r->uni_client_site_name) {
00506                 info->client_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_client_site_name);
00507                 if (!info->client_site_name) {
00508                         return WERR_GENERAL_FAILURE;
00509                 }
00510         }
00511 
00512         *info_out = info;
00513 
00514         return WERR_OK;
00515 }
00516 
00517 /* Dsr_GetDCName */
00518 
00519 WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
00520                                      TALLOC_CTX *mem_ctx,
00521                                      const char *server_name,
00522                                      const char *domain_name,
00523                                      struct GUID *domain_guid,
00524                                      struct GUID *site_guid,
00525                                      uint32_t flags,
00526                                      struct DS_DOMAIN_CONTROLLER_INFO **info_out)
00527 {
00528         prs_struct qbuf, rbuf;
00529         NET_Q_DSR_GETDCNAME q;
00530         NET_R_DSR_GETDCNAME r;
00531         char *tmp_str;
00532 
00533         ZERO_STRUCT(q);
00534         ZERO_STRUCT(r);
00535 
00536         /* Initialize input parameters */
00537 
00538         tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
00539         if (tmp_str == NULL) {
00540                 return WERR_NOMEM;
00541         }
00542 
00543         init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid,
00544                                  site_guid, flags);
00545 
00546         /* Marshall data and send request */
00547 
00548         CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME,
00549                         q, r,
00550                         qbuf, rbuf,
00551                         net_io_q_dsr_getdcname,
00552                         net_io_r_dsr_getdcname,
00553                         WERR_GENERAL_FAILURE);
00554 
00555         if (!W_ERROR_IS_OK(r.result)) {
00556                 return r.result;
00557         }
00558 
00559         r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
00560         if (!W_ERROR_IS_OK(r.result)) {
00561                 return r.result;
00562         }
00563 
00564         return WERR_OK;
00565 }
00566 
00567 /* Dsr_GetDCNameEx */
00568 
00569 WERROR rpccli_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli,
00570                                        TALLOC_CTX *mem_ctx,
00571                                        const char *server_name,
00572                                        const char *domain_name,
00573                                        struct GUID *domain_guid,
00574                                        const char *site_name,
00575                                        uint32_t flags,
00576                                        struct DS_DOMAIN_CONTROLLER_INFO **info_out)
00577 {
00578         prs_struct qbuf, rbuf;
00579         NET_Q_DSR_GETDCNAMEEX q;
00580         NET_R_DSR_GETDCNAME r;
00581         char *tmp_str;
00582 
00583         ZERO_STRUCT(q);
00584         ZERO_STRUCT(r);
00585 
00586         /* Initialize input parameters */
00587 
00588         tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
00589         if (tmp_str == NULL) {
00590                 return WERR_NOMEM;
00591         }
00592 
00593         init_net_q_dsr_getdcnameex(&q, server_name, domain_name, domain_guid,
00594                                    site_name, flags);
00595 
00596         /* Marshall data and send request */
00597 
00598         CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX,
00599                         q, r,
00600                         qbuf, rbuf,
00601                         net_io_q_dsr_getdcnameex,
00602                         net_io_r_dsr_getdcname,
00603                         WERR_GENERAL_FAILURE);
00604 
00605         if (!W_ERROR_IS_OK(r.result)) {
00606                 return r.result;
00607         }
00608 
00609         r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
00610         if (!W_ERROR_IS_OK(r.result)) {
00611                 return r.result;
00612         }
00613 
00614         return WERR_OK;
00615 }
00616 
00617 /* Dsr_GetDCNameEx */
00618 
00619 WERROR rpccli_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli,
00620                                         TALLOC_CTX *mem_ctx,
00621                                         const char *server_name,
00622                                         const char *client_account,
00623                                         uint32 mask,
00624                                         const char *domain_name,
00625                                         struct GUID *domain_guid,
00626                                         const char *site_name,
00627                                         uint32_t flags,
00628                                         struct DS_DOMAIN_CONTROLLER_INFO **info_out)
00629 {
00630         prs_struct qbuf, rbuf;
00631         NET_Q_DSR_GETDCNAMEEX2 q;
00632         NET_R_DSR_GETDCNAME r;
00633         char *tmp_str;
00634 
00635         ZERO_STRUCT(q);
00636         ZERO_STRUCT(r);
00637 
00638         /* Initialize input parameters */
00639 
00640         tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
00641         if (tmp_str == NULL) {
00642                 return WERR_NOMEM;
00643         }
00644 
00645         init_net_q_dsr_getdcnameex2(&q, server_name, domain_name, client_account,
00646                                     mask, domain_guid, site_name, flags);
00647 
00648         /* Marshall data and send request */
00649 
00650         CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX2,
00651                         q, r,
00652                         qbuf, rbuf,
00653                         net_io_q_dsr_getdcnameex2,
00654                         net_io_r_dsr_getdcname,
00655                         WERR_GENERAL_FAILURE);
00656 
00657         if (!W_ERROR_IS_OK(r.result)) {
00658                 return r.result;
00659         }
00660 
00661         r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
00662         if (!W_ERROR_IS_OK(r.result)) {
00663                 return r.result;
00664         }
00665 
00666         return WERR_OK;
00667 }
00668 
00669 
00670 /* Dsr_GetSiteName */
00671 
00672 WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
00673                                        TALLOC_CTX *mem_ctx,
00674                                        const char *computer_name,
00675                                        char **site_name)
00676 {
00677         prs_struct qbuf, rbuf;
00678         NET_Q_DSR_GETSITENAME q;
00679         NET_R_DSR_GETSITENAME r;
00680 
00681         ZERO_STRUCT(q);
00682         ZERO_STRUCT(r);
00683 
00684         /* Initialize input parameters */
00685 
00686         init_net_q_dsr_getsitename(&q, computer_name);
00687 
00688         /* Marshall data and send request */
00689 
00690         CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETSITENAME,
00691                         q, r,
00692                         qbuf, rbuf,
00693                         net_io_q_dsr_getsitename,
00694                         net_io_r_dsr_getsitename,
00695                         WERR_GENERAL_FAILURE);
00696 
00697         if (!W_ERROR_IS_OK(r.result)) {
00698                 return r.result;
00699         }
00700 
00701         if ((site_name != NULL) &&
00702             ((*site_name = rpcstr_pull_unistr2_talloc(
00703                       mem_ctx, &r.uni_site_name)) == NULL)) {
00704                 return WERR_GENERAL_FAILURE;
00705         }
00706 
00707         return WERR_OK;
00708 }
00709 
00710 
00711 
00712 /* Sam synchronisation */
00713 
00714 NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00715                                uint32 database_id, uint32 next_rid, uint32 *num_deltas,
00716                                SAM_DELTA_HDR **hdr_deltas, 
00717                                SAM_DELTA_CTR **deltas)
00718 {
00719         prs_struct qbuf, rbuf;
00720         NET_Q_SAM_SYNC q;
00721         NET_R_SAM_SYNC r;
00722         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00723         DOM_CRED clnt_creds;
00724         DOM_CRED ret_creds;
00725 
00726         ZERO_STRUCT(q);
00727         ZERO_STRUCT(r);
00728 
00729         ZERO_STRUCT(ret_creds);
00730 
00731         /* Initialise input parameters */
00732 
00733         creds_client_step(cli->dc, &clnt_creds);
00734 
00735         init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
00736                             &clnt_creds, &ret_creds, database_id, next_rid);
00737 
00738         /* Marshall data and send request */
00739 
00740         CLI_DO_RPC_COPY_SESS_KEY(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
00741                 q, r,
00742                 qbuf, rbuf,
00743                 net_io_q_sam_sync,
00744                 net_io_r_sam_sync,
00745                 NT_STATUS_UNSUCCESSFUL);
00746 
00747         /* Return results */
00748 
00749         result = r.status;
00750         *num_deltas = r.num_deltas2;
00751         *hdr_deltas = r.hdr_deltas;
00752         *deltas = r.deltas;
00753 
00754         if (!NT_STATUS_IS_ERR(result)) {
00755                 /* Check returned credentials. */
00756                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
00757                         DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
00758                         return NT_STATUS_ACCESS_DENIED;
00759                 }
00760         }
00761 
00762         return result;
00763 }
00764 
00765 /* Sam synchronisation */
00766 
00767 NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00768                                  uint32 database_id, uint64 seqnum,
00769                                  uint32 *num_deltas, 
00770                                  SAM_DELTA_HDR **hdr_deltas, 
00771                                  SAM_DELTA_CTR **deltas)
00772 {
00773         prs_struct qbuf, rbuf;
00774         NET_Q_SAM_DELTAS q;
00775         NET_R_SAM_DELTAS r;
00776         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00777         DOM_CRED clnt_creds;
00778 
00779         ZERO_STRUCT(q);
00780         ZERO_STRUCT(r);
00781 
00782         /* Initialise input parameters */
00783 
00784         creds_client_step(cli->dc, &clnt_creds);
00785 
00786         init_net_q_sam_deltas(&q, cli->dc->remote_machine,
00787                               global_myname(), &clnt_creds, 
00788                               database_id, seqnum);
00789 
00790         /* Marshall data and send request */
00791 
00792         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
00793                 q, r,
00794                 qbuf, rbuf,
00795                 net_io_q_sam_deltas,
00796                 net_io_r_sam_deltas,
00797                 NT_STATUS_UNSUCCESSFUL);
00798 
00799         /* Return results */
00800 
00801         result = r.status;
00802         *num_deltas = r.num_deltas2;
00803         *hdr_deltas = r.hdr_deltas;
00804         *deltas = r.deltas;
00805 
00806         if (!NT_STATUS_IS_ERR(result)) {
00807                 /* Check returned credentials. */
00808                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
00809                         DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
00810                         return NT_STATUS_ACCESS_DENIED;
00811                 }
00812         }
00813 
00814         return result;
00815 }
00816 
00817 /* Logon domain user */
00818 
00819 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
00820                                    TALLOC_CTX *mem_ctx,
00821                                    uint32 logon_parameters,
00822                                    const char *domain,
00823                                    const char *username,
00824                                    const char *password,
00825                                    const char *workstation,
00826                                    int logon_type)
00827 {
00828         prs_struct qbuf, rbuf;
00829         NET_Q_SAM_LOGON q;
00830         NET_R_SAM_LOGON r;
00831         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00832         DOM_CRED clnt_creds;
00833         DOM_CRED ret_creds;
00834         NET_ID_INFO_CTR ctr;
00835         NET_USER_INFO_3 user;
00836         int validation_level = 3;
00837         fstring clnt_name_slash;
00838 
00839         ZERO_STRUCT(q);
00840         ZERO_STRUCT(r);
00841         ZERO_STRUCT(ret_creds);
00842 
00843         if (workstation) {
00844                 fstr_sprintf( clnt_name_slash, "\\\\%s", workstation );
00845         } else {
00846                 fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
00847         }
00848 
00849         /* Initialise input parameters */
00850 
00851         creds_client_step(cli->dc, &clnt_creds);
00852 
00853         q.validation_level = validation_level;
00854 
00855         ctr.switch_value = logon_type;
00856 
00857         switch (logon_type) {
00858         case INTERACTIVE_LOGON_TYPE: {
00859                 unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
00860 
00861                 nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
00862 
00863                 init_id_info1(&ctr.auth.id1, domain, 
00864                               logon_parameters, /* param_ctrl */
00865                               0xdead, 0xbeef, /* LUID? */
00866                               username, clnt_name_slash,
00867                               (const char *)cli->dc->sess_key, lm_owf_user_pwd,
00868                               nt_owf_user_pwd);
00869 
00870                 break;
00871         }
00872         case NET_LOGON_TYPE: {
00873                 uint8 chal[8];
00874                 unsigned char local_lm_response[24];
00875                 unsigned char local_nt_response[24];
00876 
00877                 generate_random_buffer(chal, 8);
00878 
00879                 SMBencrypt(password, chal, local_lm_response);
00880                 SMBNTencrypt(password, chal, local_nt_response);
00881 
00882                 init_id_info2(&ctr.auth.id2, domain, 
00883                               logon_parameters, /* param_ctrl */
00884                               0xdead, 0xbeef, /* LUID? */
00885                               username, clnt_name_slash, chal,
00886                               local_lm_response, 24, local_nt_response, 24);
00887                 break;
00888         }
00889         default:
00890                 DEBUG(0, ("switch value %d not supported\n", 
00891                           ctr.switch_value));
00892                 return NT_STATUS_INVALID_INFO_CLASS;
00893         }
00894 
00895         r.user = &user;
00896 
00897         init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
00898                       &clnt_creds, &ret_creds, logon_type,
00899                       &ctr);
00900 
00901         /* Marshall data and send request */
00902 
00903         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
00904                 q, r,
00905                 qbuf, rbuf,
00906                 net_io_q_sam_logon,
00907                 net_io_r_sam_logon,
00908                 NT_STATUS_UNSUCCESSFUL);
00909 
00910         /* Return results */
00911 
00912         result = r.status;
00913 
00914         if (r.buffer_creds) {
00915                 /* Check returned credentials if present. */
00916                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
00917                         DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
00918                         return NT_STATUS_ACCESS_DENIED;
00919                 }
00920         }
00921 
00922         return result;
00923 }
00924 
00925 
00926 /** 
00927  * Logon domain user with an 'network' SAM logon 
00928  *
00929  * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
00930  **/
00931 
00932 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
00933                                            TALLOC_CTX *mem_ctx,
00934                                            uint32 logon_parameters,
00935                                            const char *server,
00936                                            const char *username,
00937                                            const char *domain,
00938                                            const char *workstation, 
00939                                            const uint8 chal[8], 
00940                                            DATA_BLOB lm_response,
00941                                            DATA_BLOB nt_response,
00942                                            NET_USER_INFO_3 *info3)
00943 {
00944         prs_struct qbuf, rbuf;
00945         NET_Q_SAM_LOGON q;
00946         NET_R_SAM_LOGON r;
00947         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00948         NET_ID_INFO_CTR ctr;
00949         int validation_level = 3;
00950         const char *workstation_name_slash;
00951         const char *server_name_slash;
00952         static uint8 zeros[16];
00953         DOM_CRED clnt_creds;
00954         DOM_CRED ret_creds;
00955         int i;
00956         
00957         ZERO_STRUCT(q);
00958         ZERO_STRUCT(r);
00959         ZERO_STRUCT(ret_creds);
00960 
00961         creds_client_step(cli->dc, &clnt_creds);
00962 
00963         if (server[0] != '\\' && server[1] != '\\') {
00964                 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
00965         } else {
00966                 server_name_slash = server;
00967         }
00968 
00969         if (workstation[0] != '\\' && workstation[1] != '\\') {
00970                 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
00971         } else {
00972                 workstation_name_slash = workstation;
00973         }
00974 
00975         if (!workstation_name_slash || !server_name_slash) {
00976                 DEBUG(0, ("talloc_asprintf failed!\n"));
00977                 return NT_STATUS_NO_MEMORY;
00978         }
00979 
00980         /* Initialise input parameters */
00981 
00982         q.validation_level = validation_level;
00983 
00984         ctr.switch_value = NET_LOGON_TYPE;
00985 
00986         init_id_info2(&ctr.auth.id2, domain,
00987                       logon_parameters, /* param_ctrl */
00988                       0xdead, 0xbeef, /* LUID? */
00989                       username, workstation_name_slash, (const uchar*)chal,
00990                       lm_response.data, lm_response.length, nt_response.data, nt_response.length);
00991  
00992         init_sam_info(&q.sam_id, server_name_slash, global_myname(),
00993                       &clnt_creds, &ret_creds, NET_LOGON_TYPE,
00994                       &ctr);
00995 
00996         r.user = info3;
00997 
00998         /* Marshall data and send request */
00999 
01000         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
01001                 q, r,
01002                 qbuf, rbuf,
01003                 net_io_q_sam_logon,
01004                 net_io_r_sam_logon,
01005                 NT_STATUS_UNSUCCESSFUL);
01006 
01007         if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
01008                 SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
01009         } else {
01010                 memset(info3->user_sess_key, '\0', 16);
01011         }
01012 
01013         if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
01014                 SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
01015         } else {
01016                 memset(info3->lm_sess_key, '\0', 8);
01017         }
01018 
01019         for (i=0; i < 7; i++) {
01020                 memset(&info3->unknown[i], '\0', 4);
01021         }
01022 
01023         /* Return results */
01024 
01025         result = r.status;
01026 
01027         if (r.buffer_creds) {
01028                 /* Check returned credentials if present. */
01029                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
01030                         DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
01031                         return NT_STATUS_ACCESS_DENIED;
01032                 }
01033         }
01034 
01035         return result;
01036 }
01037 
01038 /***************************************************************************
01039 LSA Server Password Set.
01040 ****************************************************************************/
01041 
01042 NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
01043                            const char *machine_name, const uint8 hashed_mach_pwd[16])
01044 {
01045         prs_struct rbuf;
01046         prs_struct qbuf; 
01047         DOM_CRED clnt_creds;
01048         NET_Q_SRV_PWSET q;
01049         NET_R_SRV_PWSET r;
01050         uint16 sec_chan_type = 2;
01051         NTSTATUS result;
01052 
01053         creds_client_step(cli->dc, &clnt_creds);
01054         
01055         DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
01056                  cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
01057         
01058         /* store the parameters */
01059         init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
01060                          cli->dc->mach_acct, sec_chan_type, machine_name, 
01061                          &clnt_creds, hashed_mach_pwd);
01062         
01063         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET,
01064                 q, r,
01065                 qbuf, rbuf,
01066                 net_io_q_srv_pwset,
01067                 net_io_r_srv_pwset,
01068                 NT_STATUS_UNSUCCESSFUL);
01069 
01070         result = r.status;
01071 
01072         if (!NT_STATUS_IS_OK(result)) {
01073                 /* report error code */
01074                 DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result)));
01075         }
01076 
01077         /* Always check returned credentials. */
01078         if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
01079                 DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
01080                 return NT_STATUS_ACCESS_DENIED;
01081         }
01082 
01083         return result;
01084 }
01085 
01086 /***************************************************************************
01087 LSA Server Password Set2.
01088 ****************************************************************************/
01089 
01090 NTSTATUS rpccli_net_srv_pwset2(struct rpc_pipe_client *cli,
01091                                TALLOC_CTX *mem_ctx,
01092                                const char *machine_name,
01093                                const char *clear_text_mach_pwd)
01094 {
01095         prs_struct rbuf;
01096         prs_struct qbuf;
01097         DOM_CRED clnt_creds;
01098         NET_Q_SRV_PWSET2 q;
01099         NET_R_SRV_PWSET2 r;
01100         uint16 sec_chan_type = 2;
01101         NTSTATUS result;
01102 
01103         creds_client_step(cli->dc, &clnt_creds);
01104 
01105         DEBUG(4,("cli_net_srv_pwset2: srv:%s acct:%s sc: %d mc: %s\n",
01106                  cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
01107 
01108         /* store the parameters */
01109         init_q_srv_pwset2(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
01110                           cli->dc->mach_acct, sec_chan_type, machine_name,
01111                           &clnt_creds, clear_text_mach_pwd);
01112 
01113         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET2,
01114                 q, r,
01115                 qbuf, rbuf,
01116                 net_io_q_srv_pwset2,
01117                 net_io_r_srv_pwset2,
01118                 NT_STATUS_UNSUCCESSFUL);
01119 
01120         result = r.status;
01121 
01122         if (!NT_STATUS_IS_OK(result)) {
01123                 /* report error code */
01124                 DEBUG(0,("cli_net_srv_pwset2: %s\n", nt_errstr(result)));
01125         }
01126 
01127         /* Always check returned credentials. */
01128         if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
01129                 DEBUG(0,("rpccli_net_srv_pwset2: credentials chain check failed\n"));
01130                 return NT_STATUS_ACCESS_DENIED;
01131         }
01132 
01133         return result;
01134 }

Sambaに対してSat Aug 29 21:23:15 2009に生成されました。  doxygen 1.4.7