rpc_server/srv_pipe.c

説明を見る。
00001 /* 
00002  *  Unix SMB/CIFS implementation.
00003  *  RPC Pipe client / server routines
00004  *  Almost completely rewritten by (C) Jeremy Allison 2005.
00005  *  
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *  
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *  
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 /*  this module apparently provides an implementation of DCE/RPC over a
00022  *  named pipe (IPC$ connection using SMBtrans).  details of DCE/RPC
00023  *  documentation are available (in on-line form) from the X-Open group.
00024  *
00025  *  this module should provide a level of abstraction between SMB
00026  *  and DCE/RPC, while minimising the amount of mallocs, unnecessary
00027  *  data copies, and network traffic.
00028  *
00029  */
00030 
00031 #include "includes.h"
00032 
00033 extern struct pipe_id_info pipe_names[];
00034 extern struct current_user current_user;
00035 
00036 #undef DBGC_CLASS
00037 #define DBGC_CLASS DBGC_RPC_SRV
00038 
00039 static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth)
00040 {
00041         AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state;
00042 
00043         if (a) {
00044                 auth_ntlmssp_end(&a);
00045         }
00046         auth->a_u.auth_ntlmssp_state = NULL;
00047 }
00048 
00049 /*******************************************************************
00050  Generate the next PDU to be returned from the data in p->rdata. 
00051  Handle NTLMSSP.
00052  ********************************************************************/
00053 
00054 static BOOL create_next_pdu_ntlmssp(pipes_struct *p)
00055 {
00056         RPC_HDR_RESP hdr_resp;
00057         uint32 ss_padding_len = 0;
00058         uint32 data_space_available;
00059         uint32 data_len_left;
00060         uint32 data_len;
00061         prs_struct outgoing_pdu;
00062         NTSTATUS status;
00063         DATA_BLOB auth_blob;
00064         RPC_HDR_AUTH auth_info;
00065         uint8 auth_type, auth_level;
00066         AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
00067 
00068         /*
00069          * If we're in the fault state, keep returning fault PDU's until
00070          * the pipe gets closed. JRA.
00071          */
00072 
00073         if(p->fault_state) {
00074                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
00075                 return True;
00076         }
00077 
00078         memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
00079 
00080         /* Change the incoming request header to a response. */
00081         p->hdr.pkt_type = RPC_RESPONSE;
00082 
00083         /* Set up rpc header flags. */
00084         if (p->out_data.data_sent_length == 0) {
00085                 p->hdr.flags = RPC_FLG_FIRST;
00086         } else {
00087                 p->hdr.flags = 0;
00088         }
00089 
00090         /*
00091          * Work out how much we can fit in a single PDU.
00092          */
00093 
00094         data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
00095 
00096         /*
00097          * Ensure there really is data left to send.
00098          */
00099 
00100         if(!data_len_left) {
00101                 DEBUG(0,("create_next_pdu_ntlmssp: no data left to send !\n"));
00102                 return False;
00103         }
00104 
00105         data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN -
00106                                         RPC_HDR_AUTH_LEN - NTLMSSP_SIG_SIZE;
00107 
00108         /*
00109          * The amount we send is the minimum of the available
00110          * space and the amount left to send.
00111          */
00112 
00113         data_len = MIN(data_len_left, data_space_available);
00114 
00115         /*
00116          * Set up the alloc hint. This should be the data left to
00117          * send.
00118          */
00119 
00120         hdr_resp.alloc_hint = data_len_left;
00121 
00122         /*
00123          * Work out if this PDU will be the last.
00124          */
00125 
00126         if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
00127                 p->hdr.flags |= RPC_FLG_LAST;
00128                 if (data_len_left % 8) {
00129                         ss_padding_len = 8 - (data_len_left % 8);
00130                         DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n",
00131                                 ss_padding_len ));
00132                 }
00133         }
00134 
00135         /*
00136          * Set up the header lengths.
00137          */
00138 
00139         p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
00140                         data_len + ss_padding_len +
00141                         RPC_HDR_AUTH_LEN + NTLMSSP_SIG_SIZE;
00142         p->hdr.auth_len = NTLMSSP_SIG_SIZE;
00143 
00144 
00145         /*
00146          * Init the parse struct to point at the outgoing
00147          * data.
00148          */
00149 
00150         prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
00151         prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
00152 
00153         /* Store the header in the data stream. */
00154         if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
00155                 DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR.\n"));
00156                 prs_mem_free(&outgoing_pdu);
00157                 return False;
00158         }
00159 
00160         if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
00161                 DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_RESP.\n"));
00162                 prs_mem_free(&outgoing_pdu);
00163                 return False;
00164         }
00165 
00166         /* Copy the data into the PDU. */
00167 
00168         if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
00169                 DEBUG(0,("create_next_pdu_ntlmssp: failed to copy %u bytes of data.\n", (unsigned int)data_len));
00170                 prs_mem_free(&outgoing_pdu);
00171                 return False;
00172         }
00173 
00174         /* Copy the sign/seal padding data. */
00175         if (ss_padding_len) {
00176                 char pad[8];
00177 
00178                 memset(pad, '\0', 8);
00179                 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {
00180                         DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes of pad data.\n",
00181                                         (unsigned int)ss_padding_len));
00182                         prs_mem_free(&outgoing_pdu);
00183                         return False;
00184                 }
00185         }
00186 
00187 
00188         /* Now write out the auth header and null blob. */
00189         if (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) {
00190                 auth_type = RPC_NTLMSSP_AUTH_TYPE;
00191         } else {
00192                 auth_type = RPC_SPNEGO_AUTH_TYPE;
00193         }
00194         if (p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
00195                 auth_level = RPC_AUTH_LEVEL_PRIVACY;
00196         } else {
00197                 auth_level = RPC_AUTH_LEVEL_INTEGRITY;
00198         }
00199 
00200         init_rpc_hdr_auth(&auth_info, auth_type, auth_level, ss_padding_len, 1 /* context id. */);
00201         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
00202                 DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_AUTH.\n"));
00203                 prs_mem_free(&outgoing_pdu);
00204                 return False;
00205         }
00206 
00207         /* Generate the sign blob. */
00208 
00209         switch (p->auth.auth_level) {
00210                 case PIPE_AUTH_LEVEL_PRIVACY:
00211                         /* Data portion is encrypted. */
00212                         status = ntlmssp_seal_packet(a->ntlmssp_state,
00213                                                         (unsigned char *)prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
00214                                                         data_len + ss_padding_len,
00215                                                         (unsigned char *)prs_data_p(&outgoing_pdu),
00216                                                         (size_t)prs_offset(&outgoing_pdu),
00217                                                         &auth_blob);
00218                         if (!NT_STATUS_IS_OK(status)) {
00219                                 data_blob_free(&auth_blob);
00220                                 prs_mem_free(&outgoing_pdu);
00221                                 return False;
00222                         }
00223                         break;
00224                 case PIPE_AUTH_LEVEL_INTEGRITY:
00225                         /* Data is signed. */
00226                         status = ntlmssp_sign_packet(a->ntlmssp_state,
00227                                                         (unsigned char *)prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
00228                                                         data_len + ss_padding_len,
00229                                                         (unsigned char *)prs_data_p(&outgoing_pdu),
00230                                                         (size_t)prs_offset(&outgoing_pdu),
00231                                                         &auth_blob);
00232                         if (!NT_STATUS_IS_OK(status)) {
00233                                 data_blob_free(&auth_blob);
00234                                 prs_mem_free(&outgoing_pdu);
00235                                 return False;
00236                         }
00237                         break;
00238                 default:
00239                         prs_mem_free(&outgoing_pdu);
00240                         return False;
00241         }
00242 
00243         /* Append the auth blob. */
00244         if (!prs_copy_data_in(&outgoing_pdu, (char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
00245                 DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes auth blob.\n",
00246                                 (unsigned int)NTLMSSP_SIG_SIZE));
00247                 data_blob_free(&auth_blob);
00248                 prs_mem_free(&outgoing_pdu);
00249                 return False;
00250         }
00251 
00252         data_blob_free(&auth_blob);
00253 
00254         /*
00255          * Setup the counts for this PDU.
00256          */
00257 
00258         p->out_data.data_sent_length += data_len;
00259         p->out_data.current_pdu_len = p->hdr.frag_len;
00260         p->out_data.current_pdu_sent = 0;
00261 
00262         prs_mem_free(&outgoing_pdu);
00263         return True;
00264 }
00265 
00266 /*******************************************************************
00267  Generate the next PDU to be returned from the data in p->rdata. 
00268  Return an schannel authenticated fragment.
00269  ********************************************************************/
00270 
00271 static BOOL create_next_pdu_schannel(pipes_struct *p)
00272 {
00273         RPC_HDR_RESP hdr_resp;
00274         uint32 ss_padding_len = 0;
00275         uint32 data_len;
00276         uint32 data_space_available;
00277         uint32 data_len_left;
00278         prs_struct outgoing_pdu;
00279         uint32 data_pos;
00280 
00281         /*
00282          * If we're in the fault state, keep returning fault PDU's until
00283          * the pipe gets closed. JRA.
00284          */
00285 
00286         if(p->fault_state) {
00287                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
00288                 return True;
00289         }
00290 
00291         memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
00292 
00293         /* Change the incoming request header to a response. */
00294         p->hdr.pkt_type = RPC_RESPONSE;
00295 
00296         /* Set up rpc header flags. */
00297         if (p->out_data.data_sent_length == 0) {
00298                 p->hdr.flags = RPC_FLG_FIRST;
00299         } else {
00300                 p->hdr.flags = 0;
00301         }
00302 
00303         /*
00304          * Work out how much we can fit in a single PDU.
00305          */
00306 
00307         data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
00308 
00309         /*
00310          * Ensure there really is data left to send.
00311          */
00312 
00313         if(!data_len_left) {
00314                 DEBUG(0,("create_next_pdu_schannel: no data left to send !\n"));
00315                 return False;
00316         }
00317 
00318         data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN -
00319                                         RPC_HDR_AUTH_LEN - RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
00320 
00321         /*
00322          * The amount we send is the minimum of the available
00323          * space and the amount left to send.
00324          */
00325 
00326         data_len = MIN(data_len_left, data_space_available);
00327 
00328         /*
00329          * Set up the alloc hint. This should be the data left to
00330          * send.
00331          */
00332 
00333         hdr_resp.alloc_hint = data_len_left;
00334 
00335         /*
00336          * Work out if this PDU will be the last.
00337          */
00338 
00339         if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
00340                 p->hdr.flags |= RPC_FLG_LAST;
00341                 if (data_len_left % 8) {
00342                         ss_padding_len = 8 - (data_len_left % 8);
00343                         DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n",
00344                                 ss_padding_len ));
00345                 }
00346         }
00347 
00348         p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len +
00349                                 RPC_HDR_AUTH_LEN + RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
00350         p->hdr.auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
00351 
00352         /*
00353          * Init the parse struct to point at the outgoing
00354          * data.
00355          */
00356 
00357         prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
00358         prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
00359 
00360         /* Store the header in the data stream. */
00361         if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
00362                 DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR.\n"));
00363                 prs_mem_free(&outgoing_pdu);
00364                 return False;
00365         }
00366 
00367         if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
00368                 DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_RESP.\n"));
00369                 prs_mem_free(&outgoing_pdu);
00370                 return False;
00371         }
00372 
00373         /* Store the current offset. */
00374         data_pos = prs_offset(&outgoing_pdu);
00375 
00376         /* Copy the data into the PDU. */
00377 
00378         if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
00379                 DEBUG(0,("create_next_pdu_schannel: failed to copy %u bytes of data.\n", (unsigned int)data_len));
00380                 prs_mem_free(&outgoing_pdu);
00381                 return False;
00382         }
00383 
00384         /* Copy the sign/seal padding data. */
00385         if (ss_padding_len) {
00386                 char pad[8];
00387                 memset(pad, '\0', 8);
00388                 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {
00389                         DEBUG(0,("create_next_pdu_schannel: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));
00390                         prs_mem_free(&outgoing_pdu);
00391                         return False;
00392                 }
00393         }
00394 
00395         {
00396                 /*
00397                  * Schannel processing.
00398                  */
00399                 char *data;
00400                 RPC_HDR_AUTH auth_info;
00401                 RPC_AUTH_SCHANNEL_CHK verf;
00402 
00403                 data = prs_data_p(&outgoing_pdu) + data_pos;
00404                 /* Check it's the type of reply we were expecting to decode */
00405 
00406                 init_rpc_hdr_auth(&auth_info,
00407                                 RPC_SCHANNEL_AUTH_TYPE,
00408                                 p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY ?
00409                                         RPC_AUTH_LEVEL_PRIVACY : RPC_AUTH_LEVEL_INTEGRITY,
00410                                 ss_padding_len, 1);
00411 
00412                 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
00413                         DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_AUTH.\n"));
00414                         prs_mem_free(&outgoing_pdu);
00415                         return False;
00416                 }
00417 
00418                 schannel_encode(p->auth.a_u.schannel_auth, 
00419                               p->auth.auth_level,
00420                               SENDER_IS_ACCEPTOR,
00421                               &verf, data, data_len + ss_padding_len);
00422 
00423                 if (!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, 
00424                                 &verf, &outgoing_pdu, 0)) {
00425                         prs_mem_free(&outgoing_pdu);
00426                         return False;
00427                 }
00428 
00429                 p->auth.a_u.schannel_auth->seq_num++;
00430         }
00431 
00432         /*
00433          * Setup the counts for this PDU.
00434          */
00435 
00436         p->out_data.data_sent_length += data_len;
00437         p->out_data.current_pdu_len = p->hdr.frag_len;
00438         p->out_data.current_pdu_sent = 0;
00439 
00440         prs_mem_free(&outgoing_pdu);
00441         return True;
00442 }
00443 
00444 /*******************************************************************
00445  Generate the next PDU to be returned from the data in p->rdata. 
00446  No authentication done.
00447 ********************************************************************/
00448 
00449 static BOOL create_next_pdu_noauth(pipes_struct *p)
00450 {
00451         RPC_HDR_RESP hdr_resp;
00452         uint32 data_len;
00453         uint32 data_space_available;
00454         uint32 data_len_left;
00455         prs_struct outgoing_pdu;
00456 
00457         /*
00458          * If we're in the fault state, keep returning fault PDU's until
00459          * the pipe gets closed. JRA.
00460          */
00461 
00462         if(p->fault_state) {
00463                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
00464                 return True;
00465         }
00466 
00467         memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
00468 
00469         /* Change the incoming request header to a response. */
00470         p->hdr.pkt_type = RPC_RESPONSE;
00471 
00472         /* Set up rpc header flags. */
00473         if (p->out_data.data_sent_length == 0) {
00474                 p->hdr.flags = RPC_FLG_FIRST;
00475         } else {
00476                 p->hdr.flags = 0;
00477         }
00478 
00479         /*
00480          * Work out how much we can fit in a single PDU.
00481          */
00482 
00483         data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
00484 
00485         /*
00486          * Ensure there really is data left to send.
00487          */
00488 
00489         if(!data_len_left) {
00490                 DEBUG(0,("create_next_pdu_noath: no data left to send !\n"));
00491                 return False;
00492         }
00493 
00494         data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
00495 
00496         /*
00497          * The amount we send is the minimum of the available
00498          * space and the amount left to send.
00499          */
00500 
00501         data_len = MIN(data_len_left, data_space_available);
00502 
00503         /*
00504          * Set up the alloc hint. This should be the data left to
00505          * send.
00506          */
00507 
00508         hdr_resp.alloc_hint = data_len_left;
00509 
00510         /*
00511          * Work out if this PDU will be the last.
00512          */
00513 
00514         if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
00515                 p->hdr.flags |= RPC_FLG_LAST;
00516         }
00517 
00518         /*
00519          * Set up the header lengths.
00520          */
00521 
00522         p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
00523         p->hdr.auth_len = 0;
00524 
00525         /*
00526          * Init the parse struct to point at the outgoing
00527          * data.
00528          */
00529 
00530         prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
00531         prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
00532 
00533         /* Store the header in the data stream. */
00534         if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
00535                 DEBUG(0,("create_next_pdu_noath: failed to marshall RPC_HDR.\n"));
00536                 prs_mem_free(&outgoing_pdu);
00537                 return False;
00538         }
00539 
00540         if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
00541                 DEBUG(0,("create_next_pdu_noath: failed to marshall RPC_HDR_RESP.\n"));
00542                 prs_mem_free(&outgoing_pdu);
00543                 return False;
00544         }
00545 
00546         /* Copy the data into the PDU. */
00547 
00548         if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
00549                 DEBUG(0,("create_next_pdu_noauth: failed to copy %u bytes of data.\n", (unsigned int)data_len));
00550                 prs_mem_free(&outgoing_pdu);
00551                 return False;
00552         }
00553 
00554         /*
00555          * Setup the counts for this PDU.
00556          */
00557 
00558         p->out_data.data_sent_length += data_len;
00559         p->out_data.current_pdu_len = p->hdr.frag_len;
00560         p->out_data.current_pdu_sent = 0;
00561 
00562         prs_mem_free(&outgoing_pdu);
00563         return True;
00564 }
00565 
00566 /*******************************************************************
00567  Generate the next PDU to be returned from the data in p->rdata. 
00568 ********************************************************************/
00569 
00570 BOOL create_next_pdu(pipes_struct *p)
00571 {
00572         switch(p->auth.auth_level) {
00573                 case PIPE_AUTH_LEVEL_NONE:
00574                 case PIPE_AUTH_LEVEL_CONNECT:
00575                         /* This is incorrect for auth level connect. Fixme. JRA */
00576                         return create_next_pdu_noauth(p);
00577                 
00578                 default:
00579                         switch(p->auth.auth_type) {
00580                                 case PIPE_AUTH_TYPE_NTLMSSP:
00581                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
00582                                         return create_next_pdu_ntlmssp(p);
00583                                 case PIPE_AUTH_TYPE_SCHANNEL:
00584                                         return create_next_pdu_schannel(p);
00585                                 default:
00586                                         break;
00587                         }
00588         }
00589 
00590         DEBUG(0,("create_next_pdu: invalid internal auth level %u / type %u",
00591                         (unsigned int)p->auth.auth_level,
00592                         (unsigned int)p->auth.auth_type));
00593         return False;
00594 }
00595 
00596 /*******************************************************************
00597  Process an NTLMSSP authentication response.
00598  If this function succeeds, the user has been authenticated
00599  and their domain, name and calling workstation stored in
00600  the pipe struct.
00601 *******************************************************************/
00602 
00603 static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
00604 {
00605         DATA_BLOB reply;
00606         NTSTATUS status;
00607         AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
00608 
00609         DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n", p->name));
00610 
00611         ZERO_STRUCT(reply);
00612 
00613         memset(p->user_name, '\0', sizeof(p->user_name));
00614         memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name));
00615         memset(p->domain, '\0', sizeof(p->domain));
00616         memset(p->wks, '\0', sizeof(p->wks));
00617 
00618         /* Set up for non-authenticated user. */
00619         TALLOC_FREE(p->pipe_user.nt_user_token);
00620         p->pipe_user.ut.ngroups = 0;
00621         SAFE_FREE( p->pipe_user.ut.groups);
00622 
00623         /* this has to be done as root in order to verify the password */
00624         become_root();
00625         status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
00626         unbecome_root();
00627 
00628         /* Don't generate a reply. */
00629         data_blob_free(&reply);
00630 
00631         if (!NT_STATUS_IS_OK(status)) {
00632                 return False;
00633         }
00634 
00635         /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
00636            ensure the underlying NTLMSSP flags are also set. If not we should
00637            refuse the bind. */
00638 
00639         if (p->auth.auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
00640                 if (!(a->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
00641                         DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet integrity requested "
00642                                 "but client declined signing.\n",
00643                                         p->name ));
00644                         return False;
00645                 }
00646         }
00647         if (p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
00648                 if (!(a->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
00649                         DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet privacy requested "
00650                                 "but client declined sealing.\n",
00651                                         p->name ));
00652                         return False;
00653                 }
00654         }
00655         
00656         fstrcpy(p->user_name, a->ntlmssp_state->user);
00657         fstrcpy(p->pipe_user_name, a->server_info->unix_name);
00658         fstrcpy(p->domain, a->ntlmssp_state->domain);
00659         fstrcpy(p->wks, a->ntlmssp_state->workstation);
00660 
00661         DEBUG(5,("pipe_ntlmssp_verify_final: OK: user: %s domain: %s workstation: %s\n",
00662                 p->user_name, p->domain, p->wks));
00663 
00664         /*
00665          * Store the UNIX credential data (uid/gid pair) in the pipe structure.
00666          */
00667 
00668         p->pipe_user.ut.uid = a->server_info->uid;
00669         p->pipe_user.ut.gid = a->server_info->gid;
00670         
00671         /*
00672          * Copy the session key from the ntlmssp state.
00673          */
00674 
00675         data_blob_free(&p->session_key);
00676         p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length);
00677         if (!p->session_key.data) {
00678                 return False;
00679         }
00680 
00681         p->pipe_user.ut.ngroups = a->server_info->n_groups;
00682         if (p->pipe_user.ut.ngroups) {
00683                 if (!(p->pipe_user.ut.groups = memdup(a->server_info->groups,
00684                                                 sizeof(gid_t) * p->pipe_user.ut.ngroups))) {
00685                         DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n"));
00686                         return False;
00687                 }
00688         }
00689 
00690         if (a->server_info->ptok) {
00691                 p->pipe_user.nt_user_token =
00692                         dup_nt_token(NULL, a->server_info->ptok);
00693         } else {
00694                 DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
00695                 p->pipe_user.nt_user_token = NULL;
00696                 return False;
00697         }
00698 
00699         return True;
00700 }
00701 
00702 /*******************************************************************
00703  The switch table for the pipe names and the functions to handle them.
00704 *******************************************************************/
00705 
00706 struct rpc_table {
00707         struct {
00708                 const char *clnt;
00709                 const char *srv;
00710         } pipe;
00711         struct api_struct *cmds;
00712         int n_cmds;
00713 };
00714 
00715 static struct rpc_table *rpc_lookup;
00716 static int rpc_lookup_size;
00717 
00718 /*******************************************************************
00719  This is the "stage3" NTLMSSP response after a bind request and reply.
00720 *******************************************************************/
00721 
00722 BOOL api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p)
00723 {
00724         RPC_HDR_AUTH auth_info;
00725         uint32 pad;
00726         DATA_BLOB blob;
00727 
00728         ZERO_STRUCT(blob);
00729 
00730         DEBUG(5,("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
00731 
00732         if (p->hdr.auth_len == 0) {
00733                 DEBUG(0,("api_pipe_bind_auth3: No auth field sent !\n"));
00734                 goto err;
00735         }
00736 
00737         /* 4 bytes padding. */
00738         if (!prs_uint32("pad", rpc_in_p, 0, &pad)) {
00739                 DEBUG(0,("api_pipe_bind_auth3: unmarshall of 4 byte pad failed.\n"));
00740                 goto err;
00741         }
00742 
00743         /*
00744          * Decode the authentication verifier response.
00745          */
00746 
00747         if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) {
00748                 DEBUG(0,("api_pipe_bind_auth3: unmarshall of RPC_HDR_AUTH failed.\n"));
00749                 goto err;
00750         }
00751 
00752         if (auth_info.auth_type != RPC_NTLMSSP_AUTH_TYPE) {
00753                 DEBUG(0,("api_pipe_bind_auth3: incorrect auth type (%u).\n",
00754                         (unsigned int)auth_info.auth_type ));
00755                 return False;
00756         }
00757 
00758         blob = data_blob(NULL,p->hdr.auth_len);
00759 
00760         if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) {
00761                 DEBUG(0,("api_pipe_bind_auth3: Failed to pull %u bytes - the response blob.\n",
00762                         (unsigned int)p->hdr.auth_len ));
00763                 goto err;
00764         }
00765 
00766         /*
00767          * The following call actually checks the challenge/response data.
00768          * for correctness against the given DOMAIN\user name.
00769          */
00770         
00771         if (!pipe_ntlmssp_verify_final(p, &blob)) {
00772                 goto err;
00773         }
00774 
00775         data_blob_free(&blob);
00776 
00777         p->pipe_bound = True;
00778 
00779         return True;
00780 
00781  err:
00782 
00783         data_blob_free(&blob);
00784         free_pipe_ntlmssp_auth_data(&p->auth);
00785         p->auth.a_u.auth_ntlmssp_state = NULL;
00786 
00787         return False;
00788 }
00789 
00790 /*******************************************************************
00791  Marshall a bind_nak pdu.
00792 *******************************************************************/
00793 
00794 static BOOL setup_bind_nak(pipes_struct *p)
00795 {
00796         prs_struct outgoing_rpc;
00797         RPC_HDR nak_hdr;
00798         uint16 zero = 0;
00799 
00800         /* Free any memory in the current return data buffer. */
00801         prs_mem_free(&p->out_data.rdata);
00802 
00803         /*
00804          * Marshall directly into the outgoing PDU space. We
00805          * must do this as we need to set to the bind response
00806          * header and are never sending more than one PDU here.
00807          */
00808 
00809         prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
00810         prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
00811 
00812         /*
00813          * Initialize a bind_nak header.
00814          */
00815 
00816         init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST,
00817                 p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
00818 
00819         /*
00820          * Marshall the header into the outgoing PDU.
00821          */
00822 
00823         if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) {
00824                 DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n"));
00825                 prs_mem_free(&outgoing_rpc);
00826                 return False;
00827         }
00828 
00829         /*
00830          * Now add the reject reason.
00831          */
00832 
00833         if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) {
00834                 prs_mem_free(&outgoing_rpc);
00835                 return False;
00836         }
00837 
00838         p->out_data.data_sent_length = 0;
00839         p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
00840         p->out_data.current_pdu_sent = 0;
00841 
00842         if (p->auth.auth_data_free_func) {
00843                 (*p->auth.auth_data_free_func)(&p->auth);
00844         }
00845         p->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
00846         p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
00847         p->pipe_bound = False;
00848 
00849         return True;
00850 }
00851 
00852 /*******************************************************************
00853  Marshall a fault pdu.
00854 *******************************************************************/
00855 
00856 BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
00857 {
00858         prs_struct outgoing_pdu;
00859         RPC_HDR fault_hdr;
00860         RPC_HDR_RESP hdr_resp;
00861         RPC_HDR_FAULT fault_resp;
00862 
00863         /* Free any memory in the current return data buffer. */
00864         prs_mem_free(&p->out_data.rdata);
00865 
00866         /*
00867          * Marshall directly into the outgoing PDU space. We
00868          * must do this as we need to set to the bind response
00869          * header and are never sending more than one PDU here.
00870          */
00871 
00872         prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
00873         prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
00874 
00875         /*
00876          * Initialize a fault header.
00877          */
00878 
00879         init_rpc_hdr(&fault_hdr, RPC_FAULT, RPC_FLG_FIRST | RPC_FLG_LAST | RPC_FLG_NOCALL,
00880             p->hdr.call_id, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_FAULT_LEN, 0);
00881 
00882         /*
00883          * Initialize the HDR_RESP and FAULT parts of the PDU.
00884          */
00885 
00886         memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
00887 
00888         fault_resp.status = status;
00889         fault_resp.reserved = 0;
00890 
00891         /*
00892          * Marshall the header into the outgoing PDU.
00893          */
00894 
00895         if(!smb_io_rpc_hdr("", &fault_hdr, &outgoing_pdu, 0)) {
00896                 DEBUG(0,("setup_fault_pdu: marshalling of RPC_HDR failed.\n"));
00897                 prs_mem_free(&outgoing_pdu);
00898                 return False;
00899         }
00900 
00901         if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
00902                 DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_RESP.\n"));
00903                 prs_mem_free(&outgoing_pdu);
00904                 return False;
00905         }
00906 
00907         if(!smb_io_rpc_hdr_fault("fault", &fault_resp, &outgoing_pdu, 0)) {
00908                 DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_FAULT.\n"));
00909                 prs_mem_free(&outgoing_pdu);
00910                 return False;
00911         }
00912 
00913         p->out_data.data_sent_length = 0;
00914         p->out_data.current_pdu_len = prs_offset(&outgoing_pdu);
00915         p->out_data.current_pdu_sent = 0;
00916 
00917         prs_mem_free(&outgoing_pdu);
00918         return True;
00919 }
00920 
00921 #if 0
00922 /*******************************************************************
00923  Marshall a cancel_ack pdu.
00924  We should probably check the auth-verifier here.
00925 *******************************************************************/
00926 
00927 BOOL setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p)
00928 {
00929         prs_struct outgoing_pdu;
00930         RPC_HDR ack_reply_hdr;
00931 
00932         /* Free any memory in the current return data buffer. */
00933         prs_mem_free(&p->out_data.rdata);
00934 
00935         /*
00936          * Marshall directly into the outgoing PDU space. We
00937          * must do this as we need to set to the bind response
00938          * header and are never sending more than one PDU here.
00939          */
00940 
00941         prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
00942         prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
00943 
00944         /*
00945          * Initialize a cancel_ack header.
00946          */
00947 
00948         init_rpc_hdr(&ack_reply_hdr, RPC_CANCEL_ACK, RPC_FLG_FIRST | RPC_FLG_LAST,
00949                         p->hdr.call_id, RPC_HEADER_LEN, 0);
00950 
00951         /*
00952          * Marshall the header into the outgoing PDU.
00953          */
00954 
00955         if(!smb_io_rpc_hdr("", &ack_reply_hdr, &outgoing_pdu, 0)) {
00956                 DEBUG(0,("setup_cancel_ack_reply: marshalling of RPC_HDR failed.\n"));
00957                 prs_mem_free(&outgoing_pdu);
00958                 return False;
00959         }
00960 
00961         p->out_data.data_sent_length = 0;
00962         p->out_data.current_pdu_len = prs_offset(&outgoing_pdu);
00963         p->out_data.current_pdu_sent = 0;
00964 
00965         prs_mem_free(&outgoing_pdu);
00966         return True;
00967 }
00968 #endif
00969 
00970 /*******************************************************************
00971  Ensure a bind request has the correct abstract & transfer interface.
00972  Used to reject unknown binds from Win2k.
00973 *******************************************************************/
00974 
00975 BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
00976                     RPC_IFACE* transfer, uint32 context_id)
00977 {
00978         char *pipe_name = p->name;
00979         int i=0;
00980         fstring pname;
00981         
00982         fstrcpy(pname,"\\PIPE\\");
00983         fstrcat(pname,pipe_name);
00984 
00985         DEBUG(3,("check_bind_req for %s\n", pname));
00986 
00987         /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
00988                 
00989         for ( i=0; pipe_names[i].client_pipe; i++ ) {
00990                 DEBUG(10,("checking %s\n", pipe_names[i].client_pipe));
00991                 if ( strequal(pipe_names[i].client_pipe, pname)
00992                         && (abstract->version == pipe_names[i].abstr_syntax.version) 
00993                         && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct GUID)) == 0)
00994                         && (transfer->version == pipe_names[i].trans_syntax.version)
00995                         && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct GUID)) == 0) ) {
00996                         struct api_struct       *fns = NULL;
00997                         int                     n_fns = 0;
00998                         PIPE_RPC_FNS            *context_fns;
00999                         
01000                         if ( !(context_fns = SMB_MALLOC_P(PIPE_RPC_FNS)) ) {
01001                                 DEBUG(0,("check_bind_req: malloc() failed!\n"));
01002                                 return False;
01003                         }
01004                         
01005                         /* save the RPC function table associated with this bind */
01006                         
01007                         get_pipe_fns(i, &fns, &n_fns);
01008                         
01009                         context_fns->cmds = fns;
01010                         context_fns->n_cmds = n_fns;
01011                         context_fns->context_id = context_id;
01012                         
01013                         /* add to the list of open contexts */
01014                         
01015                         DLIST_ADD( p->contexts, context_fns );
01016                         
01017                         break;
01018                 }
01019         }
01020 
01021         if(pipe_names[i].client_pipe == NULL) {
01022                 return False;
01023         }
01024 
01025         return True;
01026 }
01027 
01028 /*******************************************************************
01029  Register commands to an RPC pipe
01030 *******************************************************************/
01031 
01032 NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size)
01033 {
01034         struct rpc_table *rpc_entry;
01035 
01036         if (!clnt || !srv || !cmds) {
01037                 return NT_STATUS_INVALID_PARAMETER;
01038         }
01039 
01040         if (version != SMB_RPC_INTERFACE_VERSION) {
01041                 DEBUG(0,("Can't register rpc commands!\n"
01042                          "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
01043                          ", while this version of samba uses version %d!\n", 
01044                          version,SMB_RPC_INTERFACE_VERSION));
01045                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
01046         }
01047 
01048         /* TODO: 
01049          *
01050          * we still need to make sure that don't register the same commands twice!!!
01051          * 
01052          * --metze
01053          */
01054 
01055         /* We use a temporary variable because this call can fail and 
01056            rpc_lookup will still be valid afterwards.  It could then succeed if
01057            called again later */
01058         rpc_lookup_size++;
01059         rpc_entry = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(rpc_lookup, struct rpc_table, rpc_lookup_size);
01060         if (NULL == rpc_entry) {
01061                 rpc_lookup_size--;
01062                 DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n"));
01063                 return NT_STATUS_NO_MEMORY;
01064         } else {
01065                 rpc_lookup = rpc_entry;
01066         }
01067         
01068         rpc_entry = rpc_lookup + (rpc_lookup_size - 1);
01069         ZERO_STRUCTP(rpc_entry);
01070         rpc_entry->pipe.clnt = SMB_STRDUP(clnt);
01071         rpc_entry->pipe.srv = SMB_STRDUP(srv);
01072         rpc_entry->cmds = SMB_REALLOC_ARRAY(rpc_entry->cmds, struct api_struct, rpc_entry->n_cmds + size);
01073         if (!rpc_entry->cmds) {
01074                 return NT_STATUS_NO_MEMORY;
01075         }
01076         memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds, size * sizeof(struct api_struct));
01077         rpc_entry->n_cmds += size;
01078         
01079         return NT_STATUS_OK;
01080 }
01081 
01082 /*******************************************************************
01083  Handle a SPNEGO krb5 bind auth.
01084 *******************************************************************/
01085 
01086 static BOOL pipe_spnego_auth_bind_kerberos(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info,
01087                 DATA_BLOB *psecblob, prs_struct *pout_auth)
01088 {
01089         return False;
01090 }
01091 
01092 /*******************************************************************
01093  Handle the first part of a SPNEGO bind auth.
01094 *******************************************************************/
01095 
01096 static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p,
01097                                         RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
01098 {
01099         DATA_BLOB blob;
01100         DATA_BLOB secblob;
01101         DATA_BLOB response;
01102         DATA_BLOB chal;
01103         char *OIDs[ASN1_MAX_OIDS];
01104         int i;
01105         NTSTATUS status;
01106         BOOL got_kerberos_mechanism = False;
01107         AUTH_NTLMSSP_STATE *a = NULL;
01108         RPC_HDR_AUTH auth_info;
01109 
01110         ZERO_STRUCT(secblob);
01111         ZERO_STRUCT(chal);
01112         ZERO_STRUCT(response);
01113 
01114         /* Grab the SPNEGO blob. */
01115         blob = data_blob(NULL,p->hdr.auth_len);
01116 
01117         if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) {
01118                 DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to pull %u bytes - the SPNEGO auth header.\n",
01119                         (unsigned int)p->hdr.auth_len ));
01120                 goto err;
01121         }
01122 
01123         if (blob.data[0] != ASN1_APPLICATION(0)) {
01124                 goto err;
01125         }
01126 
01127         /* parse out the OIDs and the first sec blob */
01128         if (!parse_negTokenTarg(blob, OIDs, &secblob)) {
01129                 DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
01130                 goto err;
01131         }
01132 
01133         if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
01134                 got_kerberos_mechanism = True;
01135         }
01136 
01137         for (i=0;OIDs[i];i++) {
01138                 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));
01139                 SAFE_FREE(OIDs[i]);
01140         }
01141         DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
01142 
01143         if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
01144                 BOOL ret = pipe_spnego_auth_bind_kerberos(p, rpc_in_p, pauth_info, &secblob, pout_auth);
01145                 data_blob_free(&secblob);
01146                 data_blob_free(&blob);
01147                 return ret;
01148         }
01149 
01150         if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.auth_ntlmssp_state) {
01151                 /* Free any previous auth type. */
01152                 free_pipe_ntlmssp_auth_data(&p->auth);
01153         }
01154 
01155         /* Initialize the NTLM engine. */
01156         status = auth_ntlmssp_start(&a);
01157         if (!NT_STATUS_IS_OK(status)) {
01158                 goto err;
01159         }
01160 
01161         /*
01162          * Pass the first security blob of data to it.
01163          * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
01164          * which means we need another packet to complete the bind.
01165          */
01166 
01167         status = auth_ntlmssp_update(a, secblob, &chal);
01168 
01169         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01170                 DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
01171                 goto err;
01172         }
01173 
01174         /* Generate the response blob we need for step 2 of the bind. */
01175         response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
01176 
01177         /* Copy the blob into the pout_auth parse struct */
01178         init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);
01179         if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {
01180                 DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of RPC_HDR_AUTH failed.\n"));
01181                 goto err;
01182         }
01183 
01184         if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) {
01185                 DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of data blob failed.\n"));
01186                 goto err;
01187         }
01188 
01189         p->auth.a_u.auth_ntlmssp_state = a;
01190         p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
01191         p->auth.auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
01192 
01193         data_blob_free(&blob);
01194         data_blob_free(&secblob);
01195         data_blob_free(&chal);
01196         data_blob_free(&response);
01197 
01198         /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */
01199         return True;
01200 
01201  err:
01202 
01203         data_blob_free(&blob);
01204         data_blob_free(&secblob);
01205         data_blob_free(&chal);
01206         data_blob_free(&response);
01207 
01208         p->auth.a_u.auth_ntlmssp_state = NULL;
01209 
01210         return False;
01211 }
01212 
01213 /*******************************************************************
01214  Handle the second part of a SPNEGO bind auth.
01215 *******************************************************************/
01216 
01217 static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p,
01218                                         RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
01219 {
01220         RPC_HDR_AUTH auth_info;
01221         DATA_BLOB spnego_blob;
01222         DATA_BLOB auth_blob;
01223         DATA_BLOB auth_reply;
01224         DATA_BLOB response;
01225         AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
01226 
01227         ZERO_STRUCT(spnego_blob);
01228         ZERO_STRUCT(auth_blob);
01229         ZERO_STRUCT(auth_reply);
01230         ZERO_STRUCT(response);
01231 
01232         if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {
01233                 DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));
01234                 goto err;
01235         }
01236 
01237         /* Grab the SPNEGO blob. */
01238         spnego_blob = data_blob(NULL,p->hdr.auth_len);
01239 
01240         if (!prs_copy_data_out((char *)spnego_blob.data, rpc_in_p, p->hdr.auth_len)) {
01241                 DEBUG(0,("pipe_spnego_auth_bind_continue: Failed to pull %u bytes - the SPNEGO auth header.\n",
01242                         (unsigned int)p->hdr.auth_len ));
01243                 goto err;
01244         }
01245 
01246         if (spnego_blob.data[0] != ASN1_CONTEXT(1)) {
01247                 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));
01248                 goto err;
01249         }
01250 
01251         if (!spnego_parse_auth(spnego_blob, &auth_blob)) {
01252                 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
01253                 goto err;
01254         }
01255 
01256         /*
01257          * The following call actually checks the challenge/response data.
01258          * for correctness against the given DOMAIN\user name.
01259          */
01260         
01261         if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {
01262                 goto err;
01263         }
01264 
01265         data_blob_free(&spnego_blob);
01266         data_blob_free(&auth_blob);
01267 
01268         /* Generate the spnego "accept completed" blob - no incoming data. */
01269         response = spnego_gen_auth_response(&auth_reply, NT_STATUS_OK, OID_NTLMSSP);
01270 
01271         /* Copy the blob into the pout_auth parse struct */
01272         init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);
01273         if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {
01274                 DEBUG(0,("pipe_spnego_auth_bind_continue: marshalling of RPC_HDR_AUTH failed.\n"));
01275                 goto err;
01276         }
01277 
01278         if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) {
01279                 DEBUG(0,("pipe_spnego_auth_bind_continue: marshalling of data blob failed.\n"));
01280                 goto err;
01281         }
01282 
01283         data_blob_free(&auth_reply);
01284         data_blob_free(&response);
01285 
01286         p->pipe_bound = True;
01287 
01288         return True;
01289 
01290  err:
01291 
01292         data_blob_free(&spnego_blob);
01293         data_blob_free(&auth_blob);
01294         data_blob_free(&auth_reply);
01295         data_blob_free(&response);
01296 
01297         free_pipe_ntlmssp_auth_data(&p->auth);
01298         p->auth.a_u.auth_ntlmssp_state = NULL;
01299 
01300         return False;
01301 }
01302 
01303 /*******************************************************************
01304  Handle an schannel bind auth.
01305 *******************************************************************/
01306 
01307 static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,
01308                                         RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
01309 {
01310         RPC_HDR_AUTH auth_info;
01311         RPC_AUTH_SCHANNEL_NEG neg;
01312         RPC_AUTH_VERIFIER auth_verifier;
01313         BOOL ret;
01314         struct dcinfo *pdcinfo;
01315         uint32 flags;
01316 
01317         if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) {
01318                 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
01319                 return False;
01320         }
01321 
01322         /*
01323          * The neg.myname key here must match the remote computer name
01324          * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
01325          * operations that use credentials.
01326          */
01327 
01328         become_root();
01329         ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &pdcinfo);
01330         unbecome_root();
01331 
01332         if (!ret) {
01333                 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
01334                 return False;
01335         }
01336 
01337         p->auth.a_u.schannel_auth = TALLOC_P(p->pipe_state_mem_ctx, struct schannel_auth_struct);
01338         if (!p->auth.a_u.schannel_auth) {
01339                 TALLOC_FREE(pdcinfo);
01340                 return False;
01341         }
01342 
01343         memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key));
01344         memcpy(p->auth.a_u.schannel_auth->sess_key, pdcinfo->sess_key,
01345                         sizeof(pdcinfo->sess_key));
01346 
01347         TALLOC_FREE(pdcinfo);
01348 
01349         p->auth.a_u.schannel_auth->seq_num = 0;
01350 
01351         /*
01352          * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
01353          * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
01354          * struct of the person who opened the pipe. I need to test this further. JRA.
01355          */
01356 
01357         init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);
01358         if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {
01359                 DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n"));
01360                 return False;
01361         }
01362 
01363         /*** SCHANNEL verifier ***/
01364 
01365         init_rpc_auth_verifier(&auth_verifier, "\001", 0x0);
01366         if(!smb_io_rpc_schannel_verifier("", &auth_verifier, pout_auth, 0)) {
01367                 DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_AUTH_VERIFIER failed.\n"));
01368                 return False;
01369         }
01370 
01371         prs_align(pout_auth);
01372 
01373         flags = 5;
01374         if(!prs_uint32("flags ", pout_auth, 0, &flags)) {
01375                 return False;
01376         }
01377 
01378         DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
01379                 neg.domain, neg.myname));
01380 
01381         /* We're finished with this bind - no more packets. */
01382         p->auth.auth_data_free_func = NULL;
01383         p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL;
01384 
01385         p->pipe_bound = True;
01386 
01387         return True;
01388 }
01389 
01390 /*******************************************************************
01391  Handle an NTLMSSP bind auth.
01392 *******************************************************************/
01393 
01394 static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,
01395                                         RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
01396 {
01397         RPC_HDR_AUTH auth_info;
01398         DATA_BLOB blob;
01399         DATA_BLOB response;
01400         NTSTATUS status;
01401         AUTH_NTLMSSP_STATE *a = NULL;
01402 
01403         ZERO_STRUCT(blob);
01404         ZERO_STRUCT(response);
01405 
01406         /* Grab the NTLMSSP blob. */
01407         blob = data_blob(NULL,p->hdr.auth_len);
01408 
01409         if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) {
01410                 DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to pull %u bytes - the NTLM auth header.\n",
01411                         (unsigned int)p->hdr.auth_len ));
01412                 goto err;
01413         }
01414 
01415         if (strncmp((char *)blob.data, "NTLMSSP", 7) != 0) {
01416                 DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to read NTLMSSP in blob\n"));
01417                 goto err;
01418         }
01419 
01420         /* We have an NTLMSSP blob. */
01421         status = auth_ntlmssp_start(&a);
01422         if (!NT_STATUS_IS_OK(status)) {
01423                 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",
01424                         nt_errstr(status) ));
01425                 goto err;
01426         }
01427 
01428         status = auth_ntlmssp_update(a, blob, &response);
01429         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01430                 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n",
01431                         nt_errstr(status) ));
01432                 goto err;
01433         }
01434 
01435         data_blob_free(&blob);
01436 
01437         /* Copy the blob into the pout_auth parse struct */
01438         init_rpc_hdr_auth(&auth_info, RPC_NTLMSSP_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);
01439         if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {
01440                 DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of RPC_HDR_AUTH failed.\n"));
01441                 goto err;
01442         }
01443 
01444         if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) {
01445                 DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of data blob failed.\n"));
01446                 goto err;
01447         }
01448 
01449         p->auth.a_u.auth_ntlmssp_state = a;
01450         p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
01451         p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP;
01452 
01453         data_blob_free(&blob);
01454         data_blob_free(&response);
01455 
01456         DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
01457 
01458         /* We can't set pipe_bound True yet - we need an RPC_AUTH3 response packet... */
01459         return True;
01460 
01461   err:
01462 
01463         data_blob_free(&blob);
01464         data_blob_free(&response);
01465 
01466         free_pipe_ntlmssp_auth_data(&p->auth);
01467         p->auth.a_u.auth_ntlmssp_state = NULL;
01468         return False;
01469 }
01470 
01471 /*******************************************************************
01472  Respond to a pipe bind request.
01473 *******************************************************************/
01474 
01475 BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
01476 {
01477         RPC_HDR_BA hdr_ba;
01478         RPC_HDR_RB hdr_rb;
01479         RPC_HDR_AUTH auth_info;
01480         uint16 assoc_gid;
01481         fstring ack_pipe_name;
01482         prs_struct out_hdr_ba;
01483         prs_struct out_auth;
01484         prs_struct outgoing_rpc;
01485         int i = 0;
01486         int auth_len = 0;
01487         unsigned int auth_type = RPC_ANONYMOUS_AUTH_TYPE;
01488 
01489         /* No rebinds on a bound pipe - use alter context. */
01490         if (p->pipe_bound) {
01491                 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound pipe %s.\n", p->pipe_srv_name));
01492                 return setup_bind_nak(p);
01493         }
01494 
01495         prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
01496 
01497         /* 
01498          * Marshall directly into the outgoing PDU space. We
01499          * must do this as we need to set to the bind response
01500          * header and are never sending more than one PDU here.
01501          */
01502 
01503         prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
01504 
01505         /*
01506          * Setup the memory to marshall the ba header, and the
01507          * auth footers.
01508          */
01509 
01510         if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) {
01511                 DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
01512                 prs_mem_free(&outgoing_rpc);
01513                 return False;
01514         }
01515 
01516         if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) {
01517                 DEBUG(0,("api_pipe_bind_req: malloc out_auth failed.\n"));
01518                 prs_mem_free(&outgoing_rpc);
01519                 prs_mem_free(&out_hdr_ba);
01520                 return False;
01521         }
01522 
01523         DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
01524 
01525         /*
01526          * Try and find the correct pipe name to ensure
01527          * that this is a pipe name we support.
01528          */
01529 
01530 
01531         for (i = 0; i < rpc_lookup_size; i++) {
01532                 if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
01533                         DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
01534                                 rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
01535                         fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
01536                         break;
01537                 }
01538         }
01539 
01540         if (i == rpc_lookup_size) {
01541                 if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
01542                        DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
01543                                 p->name ));
01544                         prs_mem_free(&outgoing_rpc);
01545                         prs_mem_free(&out_hdr_ba);
01546                         prs_mem_free(&out_auth);
01547 
01548                         return setup_bind_nak(p);
01549                 }
01550 
01551                 for (i = 0; i < rpc_lookup_size; i++) {
01552                        if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
01553                                DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
01554                                          rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
01555                                fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
01556                                break;
01557                        }
01558                 }
01559 
01560                 if (i == rpc_lookup_size) {
01561                         DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
01562                         goto err_exit;
01563                 }
01564         }
01565 
01566         /* decode the bind request */
01567         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0))  {
01568                 DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n"));
01569                 goto err_exit;
01570         }
01571 
01572         /* name has to be \PIPE\xxxxx */
01573         fstrcpy(ack_pipe_name, "\\PIPE\\");
01574         fstrcat(ack_pipe_name, p->pipe_srv_name);
01575 
01576         DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
01577 
01578         /*
01579          * Check if this is an authenticated bind request.
01580          */
01581 
01582         if (p->hdr.auth_len) {
01583                 /* 
01584                  * Decode the authentication verifier.
01585                  */
01586 
01587                 if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) {
01588                         DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
01589                         goto err_exit;
01590                 }
01591 
01592                 auth_type = auth_info.auth_type;
01593 
01594                 /* Work out if we have to sign or seal etc. */
01595                 switch (auth_info.auth_level) {
01596                         case RPC_AUTH_LEVEL_INTEGRITY:
01597                                 p->auth.auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
01598                                 break;
01599                         case RPC_AUTH_LEVEL_PRIVACY:
01600                                 p->auth.auth_level = PIPE_AUTH_LEVEL_PRIVACY;
01601                                 break;
01602                         default:
01603                                 DEBUG(0,("api_pipe_bind_req: unexpected auth level (%u).\n",
01604                                         (unsigned int)auth_info.auth_level ));
01605                                 goto err_exit;
01606                 }
01607         } else {
01608                 ZERO_STRUCT(auth_info);
01609         }
01610 
01611         assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
01612 
01613         switch(auth_type) {
01614                 case RPC_NTLMSSP_AUTH_TYPE:
01615                         if (!pipe_ntlmssp_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) {
01616                                 goto err_exit;
01617                         }
01618                         assoc_gid = 0x7a77;
01619                         break;
01620 
01621                 case RPC_SCHANNEL_AUTH_TYPE:
01622                         if (!pipe_schannel_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) {
01623                                 goto err_exit;
01624                         }
01625                         break;
01626 
01627                 case RPC_SPNEGO_AUTH_TYPE:
01628                         if (!pipe_spnego_auth_bind_negotiate(p, rpc_in_p, &auth_info, &out_auth)) {
01629                                 goto err_exit;
01630                         }
01631                         break;
01632 
01633                 case RPC_ANONYMOUS_AUTH_TYPE:
01634                         /* Unauthenticated bind request. */
01635                         /* We're finished - no more packets. */
01636                         p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
01637                         /* We must set the pipe auth_level here also. */
01638                         p->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
01639                         p->pipe_bound = True;
01640                         break;
01641 
01642                 default:
01643                         DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", auth_type ));
01644                         goto err_exit;
01645         }
01646 
01647         /*
01648          * Create the bind response struct.
01649          */
01650 
01651         /* If the requested abstract synt uuid doesn't match our client pipe,
01652                 reject the bind_ack & set the transfer interface synt to all 0's,
01653                 ver 0 (observed when NT5 attempts to bind to abstract interfaces
01654                 unknown to NT4)
01655                 Needed when adding entries to a DACL from NT5 - SK */
01656 
01657         if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0],
01658                                 hdr_rb.rpc_context[0].context_id )) {
01659                 init_rpc_hdr_ba(&hdr_ba,
01660                         RPC_MAX_PDU_FRAG_LEN,
01661                         RPC_MAX_PDU_FRAG_LEN,
01662                         assoc_gid,
01663                         ack_pipe_name,
01664                         0x1, 0x0, 0x0,
01665                         &hdr_rb.rpc_context[0].transfer[0]);
01666         } else {
01667                 RPC_IFACE null_interface;
01668                 ZERO_STRUCT(null_interface);
01669                 /* Rejection reason: abstract syntax not supported */
01670                 init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN,
01671                                         RPC_MAX_PDU_FRAG_LEN, assoc_gid,
01672                                         ack_pipe_name, 0x1, 0x2, 0x1,
01673                                         &null_interface);
01674                 p->pipe_bound = False;
01675         }
01676 
01677         /*
01678          * and marshall it.
01679          */
01680 
01681         if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
01682                 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
01683                 goto err_exit;
01684         }
01685 
01686         /*
01687          * Create the header, now we know the length.
01688          */
01689 
01690         if (prs_offset(&out_auth)) {
01691                 auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
01692         }
01693 
01694         init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
01695                         p->hdr.call_id,
01696                         RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
01697                         auth_len);
01698 
01699         /*
01700          * Marshall the header into the outgoing PDU.
01701          */
01702 
01703         if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
01704                 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
01705                 goto err_exit;
01706         }
01707 
01708         /*
01709          * Now add the RPC_HDR_BA and any auth needed.
01710          */
01711 
01712         if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
01713                 DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
01714                 goto err_exit;
01715         }
01716 
01717         if (auth_len && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
01718                 DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
01719                 goto err_exit;
01720         }
01721 
01722         /*
01723          * Setup the lengths for the initial reply.
01724          */
01725 
01726         p->out_data.data_sent_length = 0;
01727         p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
01728         p->out_data.current_pdu_sent = 0;
01729 
01730         prs_mem_free(&out_hdr_ba);
01731         prs_mem_free(&out_auth);
01732 
01733         return True;
01734 
01735   err_exit:
01736 
01737         prs_mem_free(&outgoing_rpc);
01738         prs_mem_free(&out_hdr_ba);
01739         prs_mem_free(&out_auth);
01740         return setup_bind_nak(p);
01741 }
01742 
01743 /****************************************************************************
01744  Deal with an alter context call. Can be third part of 3 leg auth request for
01745  SPNEGO calls.
01746 ****************************************************************************/
01747 
01748 BOOL api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p)
01749 {
01750         RPC_HDR_BA hdr_ba;
01751         RPC_HDR_RB hdr_rb;
01752         RPC_HDR_AUTH auth_info;
01753         uint16 assoc_gid;
01754         fstring ack_pipe_name;
01755         prs_struct out_hdr_ba;
01756         prs_struct out_auth;
01757         prs_struct outgoing_rpc;
01758         int auth_len = 0;
01759 
01760         prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
01761 
01762         /* 
01763          * Marshall directly into the outgoing PDU space. We
01764          * must do this as we need to set to the bind response
01765          * header and are never sending more than one PDU here.
01766          */
01767 
01768         prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
01769 
01770         /*
01771          * Setup the memory to marshall the ba header, and the
01772          * auth footers.
01773          */
01774 
01775         if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) {
01776                 DEBUG(0,("api_pipe_alter_context: malloc out_hdr_ba failed.\n"));
01777                 prs_mem_free(&outgoing_rpc);
01778                 return False;
01779         }
01780 
01781         if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) {
01782                 DEBUG(0,("api_pipe_alter_context: malloc out_auth failed.\n"));
01783                 prs_mem_free(&outgoing_rpc);
01784                 prs_mem_free(&out_hdr_ba);
01785                 return False;
01786         }
01787 
01788         DEBUG(5,("api_pipe_alter_context: decode request. %d\n", __LINE__));
01789 
01790         /* decode the alter context request */
01791         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0))  {
01792                 DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_RB struct.\n"));
01793                 goto err_exit;
01794         }
01795 
01796         /* secondary address CAN be NULL
01797          * as the specs say it's ignored.
01798          * It MUST be NULL to have the spoolss working.
01799          */
01800         fstrcpy(ack_pipe_name,"");
01801 
01802         DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
01803 
01804         /*
01805          * Check if this is an authenticated alter context request.
01806          */
01807 
01808         if (p->hdr.auth_len != 0) {
01809                 /* 
01810                  * Decode the authentication verifier.
01811                  */
01812 
01813                 if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) {
01814                         DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_AUTH struct.\n"));
01815                         goto err_exit;
01816                 }
01817 
01818                 /*
01819                  * Currently only the SPNEGO auth type uses the alter ctx
01820                  * response in place of the NTLMSSP auth3 type.
01821                  */
01822 
01823                 if (auth_info.auth_type == RPC_SPNEGO_AUTH_TYPE) {
01824                         /* We can only finish if the pipe is unbound. */
01825                         if (!p->pipe_bound) {
01826                                 if (!pipe_spnego_auth_bind_continue(p, rpc_in_p, &auth_info, &out_auth)) {
01827                                         goto err_exit;
01828                                 }
01829                         } else {
01830                                 goto err_exit;
01831                         }
01832                 }
01833         } else {
01834                 ZERO_STRUCT(auth_info);
01835         }
01836 
01837         assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
01838 
01839         /*
01840          * Create the bind response struct.
01841          */
01842 
01843         /* If the requested abstract synt uuid doesn't match our client pipe,
01844                 reject the bind_ack & set the transfer interface synt to all 0's,
01845                 ver 0 (observed when NT5 attempts to bind to abstract interfaces
01846                 unknown to NT4)
01847                 Needed when adding entries to a DACL from NT5 - SK */
01848 
01849         if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0],
01850                                 hdr_rb.rpc_context[0].context_id )) {
01851                 init_rpc_hdr_ba(&hdr_ba,
01852                         RPC_MAX_PDU_FRAG_LEN,
01853                         RPC_MAX_PDU_FRAG_LEN,
01854                         assoc_gid,
01855                         ack_pipe_name,
01856                         0x1, 0x0, 0x0,
01857                         &hdr_rb.rpc_context[0].transfer[0]);
01858         } else {
01859                 RPC_IFACE null_interface;
01860                 ZERO_STRUCT(null_interface);
01861                 /* Rejection reason: abstract syntax not supported */
01862                 init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN,
01863                                         RPC_MAX_PDU_FRAG_LEN, assoc_gid,
01864                                         ack_pipe_name, 0x1, 0x2, 0x1,
01865                                         &null_interface);
01866                 p->pipe_bound = False;
01867         }
01868 
01869         /*
01870          * and marshall it.
01871          */
01872 
01873         if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
01874                 DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR_BA failed.\n"));
01875                 goto err_exit;
01876         }
01877 
01878         /*
01879          * Create the header, now we know the length.
01880          */
01881 
01882         if (prs_offset(&out_auth)) {
01883                 auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
01884         }
01885 
01886         init_rpc_hdr(&p->hdr, RPC_ALTCONTRESP, RPC_FLG_FIRST | RPC_FLG_LAST,
01887                         p->hdr.call_id,
01888                         RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
01889                         auth_len);
01890 
01891         /*
01892          * Marshall the header into the outgoing PDU.
01893          */
01894 
01895         if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
01896                 DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR failed.\n"));
01897                 goto err_exit;
01898         }
01899 
01900         /*
01901          * Now add the RPC_HDR_BA and any auth needed.
01902          */
01903 
01904         if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
01905                 DEBUG(0,("api_pipe_alter_context: append of RPC_HDR_BA failed.\n"));
01906                 goto err_exit;
01907         }
01908 
01909         if (auth_len && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
01910                 DEBUG(0,("api_pipe_alter_context: append of auth info failed.\n"));
01911                 goto err_exit;
01912         }
01913 
01914         /*
01915          * Setup the lengths for the initial reply.
01916          */
01917 
01918         p->out_data.data_sent_length = 0;
01919         p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
01920         p->out_data.current_pdu_sent = 0;
01921 
01922         prs_mem_free(&out_hdr_ba);
01923         prs_mem_free(&out_auth);
01924 
01925         return True;
01926 
01927   err_exit:
01928 
01929         prs_mem_free(&outgoing_rpc);
01930         prs_mem_free(&out_hdr_ba);
01931         prs_mem_free(&out_auth);
01932         return setup_bind_nak(p);
01933 }
01934 
01935 /****************************************************************************
01936  Deal with NTLMSSP sign & seal processing on an RPC request.
01937 ****************************************************************************/
01938 
01939 BOOL api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in,
01940                                         uint32 *p_ss_padding_len, NTSTATUS *pstatus)
01941 {
01942         RPC_HDR_AUTH auth_info;
01943         uint32 auth_len = p->hdr.auth_len;
01944         uint32 save_offset = prs_offset(rpc_in);
01945         AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
01946         unsigned char *data = NULL;
01947         size_t data_len;
01948         unsigned char *full_packet_data = NULL;
01949         size_t full_packet_data_len;
01950         DATA_BLOB auth_blob;
01951         
01952         *pstatus = NT_STATUS_OK;
01953 
01954         if (p->auth.auth_level == PIPE_AUTH_LEVEL_NONE || p->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
01955                 return True;
01956         }
01957 
01958         if (!a) {
01959                 *pstatus = NT_STATUS_INVALID_PARAMETER;
01960                 return False;
01961         }
01962 
01963         /* Ensure there's enough data for an authenticated request. */
01964         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
01965                         (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len > p->hdr.frag_len)) {
01966                 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len %u is too large.\n",
01967                         (unsigned int)auth_len ));
01968                 *pstatus = NT_STATUS_INVALID_PARAMETER;
01969                 return False;
01970         }
01971 
01972         /*
01973          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
01974          * after the RPC header. 
01975          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
01976          * functions as NTLMv2 checks the rpc headers also.
01977          */
01978 
01979         data = (unsigned char *)(prs_data_p(rpc_in) + RPC_HDR_REQ_LEN);
01980         data_len = (size_t)(p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - RPC_HDR_AUTH_LEN - auth_len);
01981 
01982         full_packet_data = p->in_data.current_in_pdu;
01983         full_packet_data_len = p->hdr.frag_len - auth_len;
01984 
01985         /* Pull the auth header and the following data into a blob. */
01986         if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) {
01987                 DEBUG(0,("api_pipe_ntlmssp_auth_process: cannot move offset to %u.\n",
01988                         (unsigned int)RPC_HDR_REQ_LEN + (unsigned int)data_len ));
01989                 *pstatus = NT_STATUS_INVALID_PARAMETER;
01990                 return False;
01991         }
01992 
01993         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
01994                 DEBUG(0,("api_pipe_ntlmssp_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));
01995                 *pstatus = NT_STATUS_INVALID_PARAMETER;
01996                 return False;
01997         }
01998 
01999         auth_blob.data = (unsigned char *)prs_data_p(rpc_in) + prs_offset(rpc_in);
02000         auth_blob.length = auth_len;
02001         
02002         switch (p->auth.auth_level) {
02003                 case PIPE_AUTH_LEVEL_PRIVACY:
02004                         /* Data is encrypted. */
02005                         *pstatus = ntlmssp_unseal_packet(a->ntlmssp_state,
02006                                                         data, data_len,
02007                                                         full_packet_data,
02008                                                         full_packet_data_len,
02009                                                         &auth_blob);
02010                         if (!NT_STATUS_IS_OK(*pstatus)) {
02011                                 return False;
02012                         }
02013                         break;
02014                 case PIPE_AUTH_LEVEL_INTEGRITY:
02015                         /* Data is signed. */
02016                         *pstatus = ntlmssp_check_packet(a->ntlmssp_state,
02017                                                         data, data_len,
02018                                                         full_packet_data,
02019                                                         full_packet_data_len,
02020                                                         &auth_blob);
02021                         if (!NT_STATUS_IS_OK(*pstatus)) {
02022                                 return False;
02023                         }
02024                         break;
02025                 default:
02026                         *pstatus = NT_STATUS_INVALID_PARAMETER;
02027                         return False;
02028         }
02029 
02030         /*
02031          * Return the current pointer to the data offset.
02032          */
02033 
02034         if(!prs_set_offset(rpc_in, save_offset)) {
02035                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
02036                         (unsigned int)save_offset ));
02037                 *pstatus = NT_STATUS_INVALID_PARAMETER;
02038                 return False;
02039         }
02040 
02041         /*
02042          * Remember the padding length. We must remove it from the real data
02043          * stream once the sign/seal is done.
02044          */
02045 
02046         *p_ss_padding_len = auth_info.auth_pad_len;
02047 
02048         return True;
02049 }
02050 
02051 /****************************************************************************
02052  Deal with schannel processing on an RPC request.
02053 ****************************************************************************/
02054 
02055 BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len)
02056 {
02057         uint32 data_len;
02058         uint32 auth_len;
02059         uint32 save_offset = prs_offset(rpc_in);
02060         RPC_HDR_AUTH auth_info;
02061         RPC_AUTH_SCHANNEL_CHK schannel_chk;
02062 
02063         auth_len = p->hdr.auth_len;
02064 
02065         if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
02066                 DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len ));
02067                 return False;
02068         }
02069 
02070         /*
02071          * The following is that length of the data we must verify or unseal.
02072          * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
02073          * preceeding the auth_data.
02074          */
02075 
02076         if (p->hdr.frag_len < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len) {
02077                 DEBUG(0,("Incorrect frag %u, auth %u.\n",
02078                         (unsigned int)p->hdr.frag_len,
02079                         (unsigned int)auth_len ));
02080                 return False;
02081         }
02082 
02083         data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - 
02084                 RPC_HDR_AUTH_LEN - auth_len;
02085         
02086         DEBUG(5,("data %d auth %d\n", data_len, auth_len));
02087 
02088         if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) {
02089                 DEBUG(0,("cannot move offset to %u.\n",
02090                          (unsigned int)RPC_HDR_REQ_LEN + data_len ));
02091                 return False;
02092         }
02093 
02094         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
02095                 DEBUG(0,("failed to unmarshall RPC_HDR_AUTH.\n"));
02096                 return False;
02097         }
02098 
02099         if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
02100                 DEBUG(0,("Invalid auth info %d on schannel\n",
02101                          auth_info.auth_type));
02102                 return False;
02103         }
02104 
02105         if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, &schannel_chk, rpc_in, 0)) {
02106                 DEBUG(0,("failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
02107                 return False;
02108         }
02109 
02110         if (!schannel_decode(p->auth.a_u.schannel_auth,
02111                            p->auth.auth_level,
02112                            SENDER_IS_INITIATOR,
02113                            &schannel_chk,
02114                            prs_data_p(rpc_in)+RPC_HDR_REQ_LEN, data_len)) {
02115                 DEBUG(3,("failed to decode PDU\n"));
02116                 return False;
02117         }
02118 
02119         /*
02120          * Return the current pointer to the data offset.
02121          */
02122 
02123         if(!prs_set_offset(rpc_in, save_offset)) {
02124                 DEBUG(0,("failed to set offset back to %u\n",
02125                          (unsigned int)save_offset ));
02126                 return False;
02127         }
02128 
02129         /* The sequence number gets incremented on both send and receive. */
02130         p->auth.a_u.schannel_auth->seq_num++;
02131 
02132         /*
02133          * Remember the padding length. We must remove it from the real data
02134          * stream once the sign/seal is done.
02135          */
02136 
02137         *p_ss_padding_len = auth_info.auth_pad_len;
02138 
02139         return True;
02140 }
02141 
02142 /****************************************************************************
02143  Return a user struct for a pipe user.
02144 ****************************************************************************/
02145 
02146 struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
02147 {
02148         if (p->pipe_bound &&
02149                         (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP ||
02150                         (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
02151                 memcpy(user, &p->pipe_user, sizeof(struct current_user));
02152         } else {
02153                 memcpy(user, &current_user, sizeof(struct current_user));
02154         }
02155 
02156         return user;
02157 }
02158 
02159 /****************************************************************************
02160  Find the set of RPC functions associated with this context_id
02161 ****************************************************************************/
02162 
02163 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
02164 {
02165         PIPE_RPC_FNS *fns = NULL;
02166         PIPE_RPC_FNS *tmp = NULL;
02167         
02168         if ( !list ) {
02169                 DEBUG(0,("find_pipe_fns_by_context: ERROR!  No context list for pipe!\n"));
02170                 return NULL;
02171         }
02172         
02173         for (tmp=list; tmp; tmp=tmp->next ) {
02174                 if ( tmp->context_id == context_id )
02175                         break;
02176         }
02177         
02178         fns = tmp;
02179         
02180         return fns;
02181 }
02182 
02183 /****************************************************************************
02184  Memory cleanup.
02185 ****************************************************************************/
02186 
02187 void free_pipe_rpc_context( PIPE_RPC_FNS *list )
02188 {
02189         PIPE_RPC_FNS *tmp = list;
02190         PIPE_RPC_FNS *tmp2;
02191                 
02192         while (tmp) {
02193                 tmp2 = tmp->next;
02194                 SAFE_FREE(tmp);
02195                 tmp = tmp2;
02196         }
02197 
02198         return; 
02199 }
02200 
02201 /****************************************************************************
02202  Find the correct RPC function to call for this request.
02203  If the pipe is authenticated then become the correct UNIX user
02204  before doing the call.
02205 ****************************************************************************/
02206 
02207 BOOL api_pipe_request(pipes_struct *p)
02208 {
02209         BOOL ret = False;
02210         BOOL changed_user = False;
02211         PIPE_RPC_FNS *pipe_fns;
02212         
02213         if (p->pipe_bound &&
02214                         ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) ||
02215                          (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
02216                 if(!become_authenticated_pipe_user(p)) {
02217                         prs_mem_free(&p->out_data.rdata);
02218                         return False;
02219                 }
02220                 changed_user = True;
02221         }
02222 
02223         DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));
02224         
02225         /* get the set of RPC functions for this context */
02226         
02227         pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id);
02228         
02229         if ( pipe_fns ) {
02230                 set_current_rpc_talloc(p->mem_ctx);
02231                 ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds);
02232                 set_current_rpc_talloc(NULL);   
02233         }
02234         else {
02235                 DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n",
02236                         p->hdr_req.context_id, p->name));
02237         }
02238 
02239         if (changed_user) {
02240                 unbecome_authenticated_pipe_user();
02241         }
02242 
02243         return ret;
02244 }
02245 
02246 /*******************************************************************
02247  Calls the underlying RPC function for a named pipe.
02248  ********************************************************************/
02249 
02250 BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, 
02251                 const struct api_struct *api_rpc_cmds, int n_cmds)
02252 {
02253         int fn_num;
02254         fstring name;
02255         uint32 offset1, offset2;
02256  
02257         /* interpret the command */
02258         DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
02259 
02260         slprintf(name, sizeof(name)-1, "in_%s", rpc_name);
02261         prs_dump(name, p->hdr_req.opnum, &p->in_data.data);
02262 
02263         for (fn_num = 0; fn_num < n_cmds; fn_num++) {
02264                 if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
02265                         DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name));
02266                         break;
02267                 }
02268         }
02269 
02270         if (fn_num == n_cmds) {
02271                 /*
02272                  * For an unknown RPC just return a fault PDU but
02273                  * return True to allow RPC's on the pipe to continue
02274                  * and not put the pipe into fault state. JRA.
02275                  */
02276                 DEBUG(4, ("unknown\n"));
02277                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
02278                 return True;
02279         }
02280 
02281         offset1 = prs_offset(&p->out_data.rdata);
02282 
02283         DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n", 
02284                 fn_num, api_rpc_cmds[fn_num].fn));
02285         /* do the actual command */
02286         if(!api_rpc_cmds[fn_num].fn(p)) {
02287                 DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name));
02288                 prs_mem_free(&p->out_data.rdata);
02289                 return False;
02290         }
02291 
02292         if (p->bad_handle_fault_state) {
02293                 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
02294                 p->bad_handle_fault_state = False;
02295                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
02296                 return True;
02297         }
02298 
02299         slprintf(name, sizeof(name)-1, "out_%s", rpc_name);
02300         offset2 = prs_offset(&p->out_data.rdata);
02301         prs_set_offset(&p->out_data.rdata, offset1);
02302         prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata);
02303         prs_set_offset(&p->out_data.rdata, offset2);
02304 
02305         DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));
02306 
02307         /* Check for buffer underflow in rpc parsing */
02308 
02309         if ((DEBUGLEVEL >= 10) && 
02310             (prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) {
02311                 size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data);
02312                 char *data = SMB_MALLOC(data_len);
02313 
02314                 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
02315                 if (data) {
02316                         prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, (uint32)data_len);
02317                         SAFE_FREE(data);
02318                 }
02319 
02320         }
02321 
02322         return True;
02323 }
02324 
02325 /*******************************************************************
02326 *******************************************************************/
02327 
02328 void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
02329 {
02330         struct api_struct *cmds = NULL;
02331         int               n_cmds = 0;
02332 
02333         switch ( idx ) {
02334                 case PI_LSARPC:
02335                         lsa_get_pipe_fns( &cmds, &n_cmds );
02336                         break;
02337                 case PI_LSARPC_DS:
02338                         lsa_ds_get_pipe_fns( &cmds, &n_cmds );
02339                         break;
02340                 case PI_SAMR:
02341                         samr_get_pipe_fns( &cmds, &n_cmds );
02342                         break;
02343                 case PI_NETLOGON:
02344                         netlog_get_pipe_fns( &cmds, &n_cmds );
02345                         break;
02346                 case PI_SRVSVC:
02347                         srvsvc_get_pipe_fns( &cmds, &n_cmds );
02348                         break;
02349                 case PI_WKSSVC:
02350                         wkssvc_get_pipe_fns( &cmds, &n_cmds );
02351                         break;
02352                 case PI_WINREG:
02353                         reg_get_pipe_fns( &cmds, &n_cmds );
02354                         break;
02355                 case PI_SPOOLSS:
02356                         spoolss_get_pipe_fns( &cmds, &n_cmds );
02357                         break;
02358                 case PI_NETDFS:
02359                         netdfs_get_pipe_fns( &cmds, &n_cmds );
02360                         break;
02361                 case PI_SVCCTL:
02362                         svcctl_get_pipe_fns( &cmds, &n_cmds );
02363                         break;
02364                 case PI_EVENTLOG:
02365                         eventlog_get_pipe_fns( &cmds, &n_cmds );
02366                         break;
02367                 case PI_NTSVCS:
02368                         ntsvcs_get_pipe_fns( &cmds, &n_cmds );
02369                         break;
02370 #ifdef DEVELOPER
02371                 case PI_ECHO:
02372                         echo_get_pipe_fns( &cmds, &n_cmds );
02373                         break;
02374 #endif
02375                 default:
02376                         DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx));
02377         }
02378 
02379         *fns = cmds;
02380         *n_fns = n_cmds;
02381 
02382         return;
02383 }

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