home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / samba.idb / usr / samba / src / source / rpc_pipes / pipenetlog.c.z / pipenetlog.c
Encoding:
C/C++ Source or Header  |  1998-10-28  |  24.7 KB  |  819 lines

  1.  
  2. /* 
  3.  *  Unix SMB/Netbios implementation.
  4.  *  Version 1.9.
  5.  *  RPC Pipe client / server routines
  6.  *  Copyright (C) Andrew Tridgell              1992-1997,
  7.  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
  8.  *  Copyright (C) Paul Ashton                       1997.
  9.  *  
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *  
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *  
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  */
  24.  
  25.  
  26. #include "../includes.h"
  27. #include "../trans2.h"
  28. #include "../nterr.h"
  29.  
  30. extern int DEBUGLEVEL;
  31.  
  32. extern BOOL sam_logon_in_ssb;
  33. extern pstring samlogon_user;
  34.  
  35. #ifdef NTDOMAIN
  36.  
  37. #ifdef USE_ARCFOUR
  38. void arcfour(unsigned char data[16], unsigned char data_out[16], unsigned char data_in[16]);
  39. #endif
  40.  
  41. /***********************************************************************************
  42.  make_lsa_r_req_chal:
  43.  ***********************************************************************************/
  44. static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c,
  45.                                 DOM_CHAL *srv_chal, int status)
  46. {
  47.     DEBUG(6,("make_lsa_r_req_chal: %d\n", __LINE__));
  48.     memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
  49.     r_c->status = status;
  50. }
  51.  
  52. /***********************************************************************************
  53.  lsa_reply_req_chal:
  54.  ***********************************************************************************/
  55. static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
  56.                     DOM_CHAL *srv_chal, uint32 srv_time)
  57. {
  58.     LSA_R_REQ_CHAL r_c;
  59.  
  60.     DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__));
  61.  
  62.     /* set up the LSA REQUEST CHALLENGE response */
  63.     make_lsa_r_req_chal(&r_c, srv_chal, srv_time);
  64.  
  65.     /* store the response in the SMB stream */
  66.     q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0);
  67.  
  68.     DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__));
  69.  
  70.     /* return length of SMB data stored */
  71.     return PTR_DIFF(q, base);
  72. }
  73.  
  74. /***********************************************************************************
  75.  make_lsa_r_auth_2:
  76.  ***********************************************************************************/
  77. static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
  78.                               DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
  79. {
  80.     memcpy(  r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
  81.     memcpy(&(r_a->srv_flgs)    , flgs           , sizeof(r_a->srv_flgs));
  82.     r_a->status = status;
  83. }
  84.  
  85. /***********************************************************************************
  86.  lsa_reply_auth_2:
  87.  ***********************************************************************************/
  88. static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
  89.                 DOM_CHAL *resp_cred, int status)
  90. {
  91.     LSA_R_AUTH_2 r_a;
  92.  
  93.     /* set up the LSA AUTH 2 response */
  94.  
  95.     make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
  96.  
  97.     /* store the response in the SMB stream */
  98.     q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0);
  99.  
  100.     /* return length of SMB data stored */
  101.     return PTR_DIFF(q, base);
  102. }
  103.  
  104. /***********************************************************************************
  105.  make_lsa_r_srv_pwset:
  106.  ***********************************************************************************/
  107. static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_s,
  108.                              DOM_CRED *srv_cred, int status)  
  109. {
  110.     DEBUG(5,("make_lsa_r_srv_pwset: %d\n", __LINE__));
  111.  
  112.     memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
  113.     r_s->status = status;
  114.  
  115.     DEBUG(5,("make_lsa_r_srv_pwset: %d\n", __LINE__));
  116. }
  117.  
  118. /***********************************************************************************
  119.  lsa_reply_srv_pwset:
  120.  ***********************************************************************************/
  121. static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
  122.                 DOM_CRED *srv_cred, int status)
  123. {
  124.     LSA_R_SRV_PWSET r_s;
  125.  
  126.     DEBUG(5,("lsa_srv_pwset: %d\n", __LINE__));
  127.  
  128.     /* set up the LSA Server Password Set response */
  129.     make_lsa_r_srv_pwset(&r_s, srv_cred, status);
  130.  
  131.     /* store the response in the SMB stream */
  132.     q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0);
  133.  
  134.     DEBUG(5,("lsa_srv_pwset: %d\n", __LINE__));
  135.  
  136.     /* return length of SMB data stored */
  137.     return PTR_DIFF(q, base);
  138. }
  139.  
  140. /***********************************************************************************
  141.  make_lsa_user_info:
  142.  ***********************************************************************************/
  143. static void make_lsa_user_info(LSA_USER_INFO *usr,
  144.  
  145.     NTTIME *logon_time,
  146.     NTTIME *logoff_time,
  147.     NTTIME *kickoff_time,
  148.     NTTIME *pass_last_set_time,
  149.     NTTIME *pass_can_change_time,
  150.     NTTIME *pass_must_change_time,
  151.  
  152.     char *user_name,
  153.     char *full_name,
  154.     char *logon_script,
  155.     char *profile_path,
  156.     char *home_dir,
  157.     char *dir_drive,
  158.  
  159.     uint16 logon_count,
  160.     uint16 bad_pw_count,
  161.  
  162.     uint32 user_id,
  163.     uint32 group_id,
  164.     uint32 num_groups,
  165.     DOM_GID *gids,
  166.     uint32 user_flgs,
  167.  
  168.     char sess_key[16],
  169.  
  170.     char *logon_srv,
  171.     char *logon_dom,
  172.  
  173.     char *dom_sid,
  174.     char *other_sids) /* space-delimited set of SIDs */ 
  175. {
  176.     /* only cope with one "other" sid, right now. */
  177.     /* need to count the number of space-delimited sids */
  178.     int i;
  179.     int num_other_sids = 0;
  180.  
  181.     int len_user_name    = strlen(user_name   );
  182.     int len_full_name    = strlen(full_name   );
  183.     int len_logon_script = strlen(logon_script);
  184.     int len_profile_path = strlen(profile_path);
  185.     int len_home_dir     = strlen(home_dir    );
  186.     int len_dir_drive    = strlen(dir_drive   );
  187.  
  188.     int len_logon_srv    = strlen(logon_srv);
  189.     int len_logon_dom    = strlen(logon_dom);
  190.  
  191.     usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
  192.  
  193.     usr->logon_time            = *logon_time;
  194.     usr->logoff_time           = *logoff_time;
  195.     usr->kickoff_time          = *kickoff_time;
  196.     usr->pass_last_set_time    = *pass_last_set_time;
  197.     usr->pass_can_change_time  = *pass_can_change_time;
  198.     usr->pass_must_change_time = *pass_must_change_time;
  199.  
  200.     make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   , len_user_name   , 4);
  201.     make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   , len_full_name   , 4);
  202.     make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
  203.     make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
  204.     make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    , len_home_dir    , 4);
  205.     make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   , len_dir_drive   , 4);
  206.  
  207.     usr->logon_count = logon_count;
  208.     usr->bad_pw_count = bad_pw_count;
  209.  
  210.     usr->user_id = user_id;
  211.     usr->group_id = group_id;
  212.     usr->num_groups = num_groups;
  213.     usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
  214.     usr->user_flgs = user_flgs;
  215.  
  216.     if (sess_key != NULL)
  217.     {
  218.         memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
  219.     }
  220.     else
  221.     {
  222.         bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
  223.     }
  224.  
  225.     make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
  226.     make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
  227.  
  228.     usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
  229.  
  230.     bzero(usr->padding, sizeof(usr->padding));
  231.  
  232.     num_other_sids = make_dom_sids(other_sids, usr->other_sids, LSA_MAX_SIDS);
  233.  
  234.     usr->num_other_sids = num_other_sids;
  235.     usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; 
  236.     
  237.     make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
  238.     make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
  239.     make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
  240.     make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
  241.     make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
  242.     make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
  243.  
  244.     usr->num_groups2 = num_groups;
  245.     for (i = 0; i < num_groups; i++)
  246.     {
  247.         usr->gids[i] = gids[i];
  248.     }
  249.  
  250.     make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
  251.     make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
  252.  
  253.     make_dom_sid(&(usr->dom_sid), dom_sid);
  254.     /* "other" sids are set up above */
  255. }
  256.  
  257.  
  258. /***********************************************************************************
  259.  lsa_reply_sam_logon:
  260.  ***********************************************************************************/
  261. static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
  262.                 DOM_CRED *srv_cred, LSA_USER_INFO *user_info)
  263. {
  264.     LSA_R_SAM_LOGON r_s;
  265.  
  266.     /* XXXX maybe we want to say 'no', reject the client's credentials */
  267.     r_s.buffer_creds = 1; /* yes, we have valid server credentials */
  268.     memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
  269.  
  270.     /* store the user information, if there is any. */
  271.     r_s.user = user_info;
  272.     if (user_info != NULL && user_info->ptr_user_info != 0)
  273.     {
  274.         r_s.switch_value = 3; /* indicates type of validation user info */
  275.         r_s.status = 0;
  276.     }
  277.     else
  278.     {
  279.         r_s.switch_value = 0; /* don't know what this value is supposed to be */
  280.         r_s.status = 0xC000000|NT_STATUS_NO_SUCH_USER;
  281.     }
  282.  
  283.     r_s.auth_resp = 1; /* authoritative response */
  284.  
  285.     /* store the response in the SMB stream */
  286.     q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0);
  287.  
  288.     /* return length of SMB data stored */
  289.     return PTR_DIFF(q, base);
  290. }
  291.  
  292.  
  293. /***********************************************************************************
  294.  lsa_reply_sam_logoff:
  295.  ***********************************************************************************/
  296. static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
  297.                 DOM_CRED *srv_cred, 
  298.                 uint32 status)
  299. {
  300.     LSA_R_SAM_LOGOFF r_s;
  301.  
  302.     /* XXXX maybe we want to say 'no', reject the client's credentials */
  303.     r_s.buffer_creds = 1; /* yes, we have valid server credentials */
  304.     memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
  305.  
  306.     r_s.status = status;
  307.  
  308.     /* store the response in the SMB stream */
  309.     q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0);
  310.  
  311.     /* return length of SMB data stored */
  312.     return PTR_DIFF(q, base);
  313. }
  314.  
  315. /****************************************************************************
  316.   gets a machine password entry.  checks access rights of the host.
  317. ****************************************************************************/
  318. static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
  319. {
  320.     struct smb_passwd *smb_pass;
  321.  
  322.     if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
  323.                       client_name(), client_addr()))
  324.     {
  325.         DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
  326.         return False;
  327.     }
  328.  
  329.     become_root(True);
  330.     smb_pass = get_smbpwd_entry(mach_acct, 0);
  331.     unbecome_root(True);
  332.  
  333.     if (smb_pass != NULL)
  334.     {
  335.         memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
  336.         dump_data(5, md4pw, 16);
  337.  
  338.         return True;
  339.     }
  340.     DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
  341.     return False;
  342. }
  343.  
  344. /***********************************************************************************
  345.  api_lsa_req_chal
  346.  ***********************************************************************************/
  347. static void api_lsa_req_chal( int cnum, uint16 vuid,
  348.                               user_struct *vuser,
  349.                               char *param, char *data,
  350.                               char **rdata, int *rdata_len )
  351. {
  352.     LSA_Q_REQ_CHAL q_r;
  353.     uint32 status = 0x0;
  354.  
  355.     fstring mach_acct;
  356.     fstring mach_name;
  357.  
  358.     /* grab the challenge... */
  359.     lsa_io_q_req_chal(True, &q_r, data + 0x18, data, 4, 0);
  360.  
  361.     fstrcpy(mach_acct, unistrn2(q_r.uni_logon_clnt.buffer,
  362.                                 q_r.uni_logon_clnt.uni_str_len));
  363.  
  364.     fstrcpy(mach_name, mach_acct);
  365.     strlower(mach_name);
  366.  
  367.     fstrcat(mach_acct, "$");
  368.  
  369.     if (get_md4pw(vuser->dc.md4pw, mach_name, mach_acct))
  370.     {
  371.         /* copy the client credentials */
  372.         memcpy(vuser->dc.clnt_chal.data          , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
  373.         memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
  374.  
  375.         /* create a server challenge for the client */
  376.         /* PAXX: set these to random values. */
  377.         /* lkcl: paul, you mentioned that it doesn't really matter much */
  378.         SIVAL(vuser->dc.srv_chal.data, 0, 0x11111111);
  379.         SIVAL(vuser->dc.srv_chal.data, 4, 0x11111111);
  380.         memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
  381.  
  382.         /* from client / server challenges and md4 password, generate sess key */
  383.         cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
  384.                            vuser->dc.md4pw, vuser->dc.sess_key);
  385.     }
  386.     else
  387.     {
  388.         /* lkclXXXX take a guess at a good error message to return :-) */
  389.         status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
  390.     }
  391.  
  392.     /* construct reply. */
  393.     *rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata,
  394.                     &(vuser->dc.srv_chal), status);
  395.  
  396. }
  397.  
  398. /***********************************************************************************
  399.  api_lsa_auth_2:
  400.  ***********************************************************************************/
  401. static void api_lsa_auth_2( user_struct *vuser,
  402.                             char *param, char *data,
  403.                             char **rdata, int *rdata_len )
  404. {
  405.     LSA_Q_AUTH_2 q_a;
  406.  
  407.     DOM_CHAL srv_cred;
  408.     UTIME srv_time;
  409.  
  410.     srv_time.time = 0;
  411.  
  412.     /* grab the challenge... */
  413.     lsa_io_q_auth_2(True, &q_a, data + 0x18, data, 4, 0);
  414.  
  415.     /* check that the client credentials are valid */
  416.     cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
  417.                 &(vuser->dc.clnt_cred.challenge), srv_time);
  418.  
  419.     /* create server challenge for inclusion in the reply */
  420.     cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
  421.  
  422.     /* copy the received client credentials for use next time */
  423.     memcpy(vuser->dc.clnt_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
  424.     memcpy(vuser->dc.srv_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
  425.  
  426.     /* construct reply. */
  427.     *rdata_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata,
  428.                     &srv_cred, 0x0);
  429. }
  430.  
  431.  
  432. /***********************************************************************************
  433.  api_lsa_srv_pwset:
  434.  ***********************************************************************************/
  435. static void api_lsa_srv_pwset( user_struct *vuser,
  436.                                char *param, char *data,
  437.                                char **rdata, int *rdata_len )
  438. {
  439. #ifdef USE_ARCFOUR
  440.     char pwd[16];
  441. #endif
  442.  
  443.     LSA_Q_SRV_PWSET q_a;
  444.     uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
  445.     DOM_CRED srv_cred;
  446.     pstring mach_acct;
  447.     struct smb_passwd *smb_pass;
  448.     BOOL ret;
  449.  
  450.     /* grab the challenge and encrypted password ... */
  451.     lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data, 4, 0);
  452.  
  453.     /* checks and updates credentials.  creates reply credentials */
  454.     if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
  455.                     &(q_a.clnt_id.cred), &srv_cred))
  456.     {
  457.         memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
  458.  
  459.         DEBUG(5,("api_lsa_srv_pwset: %d\n", __LINE__));
  460.  
  461.         pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
  462.                                     q_a.clnt_id.login.uni_acct_name.uni_str_len));
  463.  
  464.         DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
  465.  
  466.         become_root(True);
  467.         smb_pass = get_smbpwd_entry(mach_acct, 0);
  468.         unbecome_root(True);
  469.  
  470. #ifdef USE_ARCFOUR
  471.         if (smb_pass != NULL)
  472.         {
  473.             unsigned char arc4_key[16];
  474.             memset(arc4_key, 0, 16);
  475.             memcpy(arc4_key, vuser->dc.sess_key, 8);
  476.  
  477.             arcfour(arc4_key, pwd, q_a.pwd);
  478.  
  479. #ifdef DEBUG_PASSWORD
  480.             DEBUG(100,("arcfour decrypt of machine password:"));
  481.             dump_data(100, pwd, 16);
  482. #endif
  483.  
  484.             /* lies!  nt and lm passwords are _not_ the same: don't care */
  485.             smb_pass->smb_passwd    = pwd;
  486.             smb_pass->smb_nt_passwd = pwd;
  487.  
  488.             become_root(True);
  489.             ret = mod_smbpwd_entry(smb_pass);
  490.             unbecome_root(True);
  491.  
  492.             if (ret)
  493.             {
  494.                 /* hooray! */
  495.                 status = 0x0;
  496.             }
  497.         }
  498. #else
  499.         /* sorry.  have to refuse the password change.
  500.            this _is_ ok, because NT accepts this, and the
  501.            machine password stays at its default value..
  502.          */
  503. #endif
  504.  
  505.         DEBUG(5,("api_lsa_srv_pwset: %d\n", __LINE__));
  506.     }
  507.     else
  508.     {
  509.         /* lkclXXXX take a guess at a sensible error code to return... */
  510.         status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
  511.     }
  512.  
  513.     /* construct reply.  always indicate failure.  nt keeps going... */
  514.     *rdata_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata,
  515.                     &srv_cred, status);
  516. }
  517.  
  518.  
  519. /***********************************************************************************
  520.  api_lsa_sam_logoff:
  521.  ***********************************************************************************/
  522. static void api_lsa_sam_logoff( user_struct *vuser,
  523.                                char *param, char *data,
  524.                                char **rdata, int *rdata_len )
  525. {
  526.     LSA_Q_SAM_LOGOFF q_l;
  527.     DOM_ID_INFO_1 id1;    
  528.  
  529.     DOM_CRED srv_cred;
  530.  
  531.     /* the DOM_ID_INFO_1 structure is a bit big.  plus we might want to
  532.        dynamically allocate it inside lsa_io_q_sam_logon, at some point */
  533.     q_l.sam_id.auth.id1 = &id1;
  534.  
  535.     /* grab the challenge... */
  536.     lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data, 4, 0);
  537.  
  538.     /* checks and updates credentials.  creates reply credentials */
  539.     deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
  540.                     &(q_l.sam_id.client.cred), &srv_cred);
  541.     memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
  542.  
  543.     /* construct reply.  always indicate success */
  544.     *rdata_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata,
  545.                     &srv_cred,
  546.                     0x0);
  547. }
  548.  
  549.  
  550. /***********************************************************************************
  551.  api_lsa_sam_logon:
  552.  ***********************************************************************************/
  553. static void api_lsa_sam_logon( user_struct *vuser,
  554.                                char *param, char *data,
  555.                                char **rdata, int *rdata_len )
  556. {
  557.     LSA_Q_SAM_LOGON q_l;
  558.     DOM_ID_INFO_1 id1;    
  559.     LSA_USER_INFO usr_info;
  560.  
  561.     DOM_CRED srv_cred;
  562.  
  563.     /* the DOM_ID_INFO_1 structure is a bit big.  plus we might want to
  564.        dynamically allocate it inside lsa_io_q_sam_logon, at some point */
  565.     q_l.sam_id.auth.id1 = &id1;
  566.  
  567.     lsa_io_q_sam_logon(True, &q_l, data + 0x18, data, 4, 0);
  568.  
  569.     /* checks and updates credentials.  creates reply credentials */
  570.     deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
  571.                     &(q_l.sam_id.client.cred), &srv_cred);
  572.     memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
  573.  
  574.     if (vuser != NULL)
  575.     {
  576.         DOM_GID gids[LSA_MAX_GROUPS];
  577.         int num_gids = 0;
  578.         NTTIME dummy_time;
  579.         pstring logon_script;
  580.         pstring profile_path;
  581.         pstring home_dir;
  582.         pstring home_drive;
  583.         pstring my_name;
  584.         pstring my_workgroup;
  585.         pstring domain_groups;
  586.         pstring dom_sid;
  587.         pstring other_sids;
  588.         fstring tmp;
  589.         extern pstring myname;
  590.         uint32 r_uid;
  591.         uint32 r_gid;
  592.         UNISTR2 *uni_samlogon_user = &(q_l.sam_id.auth.id1->uni_user_name);
  593.         struct smb_passwd *smb_pass;
  594.         BOOL pwd_ok = False;
  595.  
  596. #ifdef USE_ARCFOUR
  597.         char nt_pwd[16];
  598.         char lm_pwd[16];
  599. #endif
  600.  
  601.         /* set up pointer indicating user/password failed to be found */
  602.         usr_info.ptr_user_info = 0;
  603.  
  604.         dummy_time.low  = 0xffffffff;
  605.         dummy_time.high = 0x7fffffff;
  606.  
  607.         get_myname(myname, NULL);
  608.  
  609.         pstrcpy(samlogon_user, unistrn2(uni_samlogon_user->buffer,
  610.                                         uni_samlogon_user->uni_str_len));
  611.  
  612.         DEBUG(3,("SAM Logon. Domain:[%s].  User:[%s]\n",
  613.                   lp_workgroup(), samlogon_user));
  614.  
  615.         become_root(True);
  616.         smb_pass = get_smbpwd_entry(samlogon_user, 0);
  617.         unbecome_root(True);
  618.  
  619. #ifdef USE_ARCFOUR
  620.         if (smb_pass != NULL)
  621.         {
  622.             unsigned char arc4_key[16];
  623.             memset(arc4_key, 0, 16);
  624.             memcpy(arc4_key, vuser->dc.sess_key, 8);
  625.  
  626.             arcfour(arc4_key, lm_pwd, q_l.sam_id.auth.id1->arc4_lm_owf.data);
  627.             arcfour(arc4_key, nt_pwd, q_l.sam_id.auth.id1->arc4_nt_owf.data);
  628.  
  629. #ifdef DEBUG_PASSWORD
  630.             DEBUG(100,("arcfour decrypt of lm owf password:"));
  631.             dump_data(100, lm_pwd, 16);
  632.  
  633.             DEBUG(100,("arcfour decrypt of nt owf password:"));
  634.             dump_data(100, nt_pwd, 16);
  635. #endif
  636.  
  637.             pwd_ok = memcmp(smb_pass->smb_passwd   , lm_pwd, 16) == 0 ||
  638.                      memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) == 0;
  639.         }
  640. #else
  641.         /* sorry.  have to assume that the password is always ok.
  642.            this _is_ ok, because the LSA SAM Logon is nothing to do
  643.            with SMB connections to shares.
  644.          */
  645.         pwd_ok = True;
  646. #endif
  647.  
  648.         if (smb_pass != NULL && pwd_ok)
  649.         {
  650.             /* hack to get standard_sub_basic() to use the sam logon username */
  651.             sam_logon_in_ssb = True;
  652.  
  653.             pstrcpy(logon_script, lp_logon_script     ());
  654.             pstrcpy(profile_path, lp_logon_path       ());
  655.             pstrcpy(dom_sid     , lp_domain_sid       ());
  656.             pstrcpy(other_sids  , lp_domain_other_sids());
  657.             pstrcpy(my_workgroup, lp_workgroup        ());
  658.  
  659.             pstrcpy(home_drive  , lp_logon_drive      ());
  660.             pstrcpy(home_dir    , lp_logon_home       ());
  661.  
  662.             pstrcpy(my_name     , myname                );
  663.             strupper(my_name);
  664.  
  665.             /* any additional groups this user is in.  e.g power users */
  666.             pstrcpy(domain_groups, lp_domain_groups());
  667.  
  668.             /* can only be a user or a guest.  cannot be guest _and_ admin */
  669.             if (user_in_list(samlogon_user, lp_domain_guest_users()))
  670.             {
  671.                 slprintf(tmp, sizeof(tmp)-1," %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
  672.                 pstrcat(domain_groups, tmp);
  673.  
  674.                 DEBUG(3,("domain guest access %s granted\n", tmp));
  675.             }
  676.             else
  677.             {
  678.                 slprintf(tmp, sizeof(tmp)-1, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
  679.                 fstrcat(domain_groups, tmp);
  680.  
  681.                 DEBUG(3,("domain user access %s granted\n", tmp));
  682.  
  683.                 if (user_in_list(samlogon_user, lp_domain_admin_users()))
  684.                 {
  685.                     slprintf(tmp, sizeof(tmp)-1," %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
  686.                     pstrcat(domain_groups, tmp);
  687.  
  688.                     DEBUG(3,("domain admin access %s granted\n", tmp));
  689.                 }
  690.             }
  691.  
  692.             num_gids = make_dom_gids(domain_groups, gids);
  693.  
  694.             sam_logon_in_ssb = False;
  695.         }
  696.  
  697.         if (pwd_ok && name_to_rid(samlogon_user, &r_uid, &r_gid))
  698.         {
  699.             make_lsa_user_info(&usr_info,
  700.  
  701.                        &dummy_time, /* logon_time */
  702.                        &dummy_time, /* logoff_time */
  703.                        &dummy_time, /* kickoff_time */
  704.                        &dummy_time, /* pass_last_set_time */
  705.                        &dummy_time, /* pass_can_change_time */
  706.                        &dummy_time, /* pass_must_change_time */
  707.  
  708.                        samlogon_user, /* user_name */
  709.                        vuser->real_name, /* full_name */
  710.                        logon_script, /* logon_script */
  711.                        profile_path, /* profile_path */
  712.                        home_dir, /* home_dir */
  713.                        home_drive, /* dir_drive */
  714.  
  715.                        0, /* logon_count */
  716.                        0, /* bad_pw_count */
  717.  
  718.                        r_uid, /* RID user_id */
  719.                        r_gid, /* RID group_id */
  720.                        num_gids,    /* uint32 num_groups */
  721.                        gids, /* DOM_GID *gids */
  722.                        0x20, /* uint32 user_flgs */
  723.  
  724.                        NULL, /* char sess_key[16] */
  725.  
  726.                        my_name     , /* char *logon_srv */
  727.                        my_workgroup, /* char *logon_dom */
  728.  
  729.                        dom_sid,     /* char *dom_sid */
  730.                        other_sids); /* char *other_sids */
  731.         }
  732.     }
  733.  
  734.  
  735.     *rdata_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata,
  736.                     &srv_cred, &usr_info);
  737. }
  738.  
  739.  
  740. /***********************************************************************************
  741.  api_netlogrpcTNP:
  742.  ***********************************************************************************/
  743. BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
  744.              int mdrcnt,int mprcnt,
  745.              char **rdata,char **rparam,
  746.              int *rdata_len,int *rparam_len)
  747. {
  748.     user_struct *vuser;
  749.  
  750.     RPC_HDR_RR hdr;
  751.  
  752.     if (data == NULL)
  753.     {
  754.         DEBUG(2,("api_netlogrpcTNP: NULL data received\n"));
  755.         return False;
  756.     }
  757.  
  758.     smb_io_rpc_hdr_rr(True, &hdr, data, data, 4, 0);
  759.  
  760.     DEBUG(4,("netlogon TransactNamedPipe op %x\n",hdr.opnum));
  761.  
  762.     if ((vuser = get_valid_user_struct(uid)) == NULL) return False;
  763.  
  764.     DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
  765.  
  766.     switch (hdr.opnum)
  767.     {
  768.         case LSA_REQCHAL:
  769.         {
  770.             DEBUG(3,("LSA_REQCHAL\n"));
  771.             api_lsa_req_chal(cnum, uid, vuser, param, data, rdata, rdata_len);
  772.             create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
  773.             break;
  774.         }
  775.  
  776.         case LSA_AUTH2:
  777.         {
  778.             DEBUG(3,("LSA_AUTH2\n"));
  779.             api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
  780.             create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
  781.             break;
  782.         }
  783.  
  784.         case LSA_SRVPWSET:
  785.         {
  786.             DEBUG(3,("LSA_SRVPWSET\n"));
  787.             api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
  788.             create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
  789.             break;
  790.         }
  791.  
  792.         case LSA_SAMLOGON:
  793.         {
  794.             DEBUG(3,("LSA_SAMLOGON\n"));
  795.             api_lsa_sam_logon(vuser, param, data, rdata, rdata_len);
  796.             create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
  797.             break;
  798.         }
  799.  
  800.         case LSA_SAMLOGOFF:
  801.         {
  802.             DEBUG(3,("LSA_SAMLOGOFF\n"));
  803.             api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len);
  804.             create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
  805.             break;
  806.         }
  807.  
  808.         default:
  809.         {
  810.               DEBUG(4, ("**** netlogon, unknown code: %lx\n", hdr.opnum));
  811.             break;
  812.         }
  813.     }
  814.  
  815.     return True;
  816. }
  817.  
  818. #endif /* NTDOMAIN */
  819.