Ejemplo n.º 1
0
int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
		     char *PassWord)

{
  struct RFCNB_Pkt *pkt;
  int param_len, pkt_len, pass_len;
  char *p, pword[256];

  /* First we need a packet etc ... but we need to know what protocol has  */
  /* been negotiated to figure out if we can do it and what SMB format to  */
  /* use ...                                                               */

  if (Con_Handle -> protocol < SMB_P_LanMan1) {

    SMBlib_errno = SMBlibE_ProtLow;
    return(SMBlibE_BAD);

  }

  strcpy(pword, PassWord);
  if (Con_Handle -> encrypt_passwords)
  {
    pass_len=24;
    SMBencrypt((uchar *) PassWord, (uchar *)Con_Handle -> Encrypt_Key,(uchar *)pword);
  }
  else
	pass_len=strlen(pword);


  /* Now build the correct structure */

  if (Con_Handle -> protocol < SMB_P_NT1) {

    param_len = strlen(UserName) + 1 + pass_len + 1 +
                strlen(Con_Handle -> PDomain) + 1 +
	        strlen(Con_Handle -> OSName) + 1;

    pkt_len = SMB_ssetpLM_len + param_len;

    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);

    if (pkt == NULL) {

      SMBlib_errno = SMBlibE_NoSpace;
      return(SMBlibE_BAD); /* Should handle the error */

    }

    bzero(SMB_Hdr(pkt), SMB_ssetpLM_len);
    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);

    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);

    /* Now copy the param strings in with the right stuff */

    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);

    /* Copy  in password, then the rest. Password has a null at end */

    memcpy(p, pword, pass_len);

    p = p + pass_len + 1;

    strcpy(p, UserName);
    p = p + strlen(UserName);
    *p = 0;

    p = p + 1;

    strcpy(p, Con_Handle -> PDomain);
    p = p + strlen(Con_Handle -> PDomain);
    *p = 0;
    p = p + 1;

    strcpy(p, Con_Handle -> OSName);
    p = p + strlen(Con_Handle -> OSName);
    *p = 0;

  }
  else {

    /* We don't admit to UNICODE support ... */

    param_len = strlen(UserName) + 1 + pass_len +
                strlen(Con_Handle -> PDomain) + 1 +
	        strlen(Con_Handle -> OSName) + 1 +
		strlen(Con_Handle -> LMType) + 1;

    pkt_len = SMB_ssetpNTLM_len + param_len;

    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);

    if (pkt == NULL) {

      SMBlib_errno = SMBlibE_NoSpace;
      return(-1); /* Should handle the error */

    }

    bzero(SMB_Hdr(pkt), SMB_ssetpNTLM_len);
    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);

    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);

    /* Now copy the param strings in with the right stuff */

    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);

    /* Copy  in password, then the rest. Password has no null at end */

    memcpy(p, pword, pass_len);

    p = p + pass_len;

    strcpy(p, UserName);
    p = p + strlen(UserName);
    *p = 0;

    p = p + 1;

    strcpy(p, Con_Handle -> PDomain);
    p = p + strlen(Con_Handle -> PDomain);
  *p = 0;
    p = p + 1;

    strcpy(p, Con_Handle -> OSName);
    p = p + strlen(Con_Handle -> OSName);
    *p = 0;
    p = p + 1;

    strcpy(p, Con_Handle -> LMType);
    p = p + strlen(Con_Handle -> LMType);
    *p = 0;

  }

  /* Now send it and get a response */

  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0){

#ifdef DEBUG
    fprintf(stderr, "Error sending SessSetupX request\n");
#endif

    RFCNB_Free_Pkt(pkt);
    SMBlib_errno = SMBlibE_SendFailed;
    return(SMBlibE_BAD);

  }

  /* Now get the response ... */

  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
    fprintf(stderr, "Error receiving response to SessSetupAndX\n");
#endif

    RFCNB_Free_Pkt(pkt);
    SMBlib_errno = SMBlibE_RecvFailed;
    return(SMBlibE_BAD);

  }

  /* Check out the response type ... */

  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */

#ifdef DEBUG
    fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n",
	    CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
	    SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
#endif

    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
    RFCNB_Free_Pkt(pkt);
    SMBlib_errno = SMBlibE_Remote;
    return(SMBlibE_BAD);

  }
/** @@@ mdz: check for guest login { **/
       if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1)
       {
               /* do we allow guest login? NO! */
               return(SMBlibE_BAD);

       }
 /** @@@ mdz: } **/


#ifdef DEBUG
  fprintf(stderr, "SessSetupAndX response. Action = %i\n",
          SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
#endif

  /* Now pick up the UID for future reference ... */

  Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
  RFCNB_Free_Pkt(pkt);

  return(0);

}
Ejemplo n.º 2
0
/* Negotiate the protocol we will use from the list passed in Prots we
 * return the index of the accepted protocol in NegProt, -1 *indicates
 * none acceptible, and our return value is 0 if ok, <0 if problems */
static int 
SMB_Negotiate(SMB_Handle_Type Con_Handle, char *Prots[])
{
    struct RFCNB_Pkt *pkt;
    int prots_len, i, pkt_len, prot, alloc_len;
    char *p;

    /* Figure out how long the prot list will be and allocate space
     * for it */
    prots_len = 0;

    for (i = 0; Prots[i] != NULL; i++) {
        prots_len = prots_len + strlen(Prots[i]) + 2;   /* Account for
                                                         * null etc */
    }

    /* The -1 accounts for the one byte smb_buf we have because some
     * systems don't like char msg_buf[] */
    pkt_len = SMB_negp_len + prots_len;

    /* Make sure that the pkt len is long enough for the max
     * response...  Which is a problem, because the encryption key len
     * eec may be long */
    if (pkt_len < (SMB_hdr_wct_offset + (19 * 2) + 40))
        alloc_len = SMB_hdr_wct_offset + (19 * 2) + 40;
    else
        alloc_len = pkt_len;

    pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(alloc_len);
    if (pkt == NULL) {
        SMBlib_errno = SMBlibE_NoSpace;
        return (SMBlibE_BAD);
    }
    /* Now plug in the bits we need */
    bzero(SMB_Hdr(pkt), SMB_negp_len);
    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBnegprot;
    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid);
    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;

    SSVAL(SMB_Hdr(pkt), SMB_negp_bcc_offset, prots_len);

    /* Now copy the prot strings in with the right stuff */
    p = (char *) (SMB_Hdr(pkt) + SMB_negp_buf_offset);

    for (i = 0; Prots[i] != NULL; i++) {
        *p = SMBdialectID;
        strcpy(p + 1, Prots[i]);
        p = p + strlen(Prots[i]) + 2;   /* Adjust len of p for null
                                         * plus dialectID */
    }

    /* Now send the packet and sit back ... */
    if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) {
#ifdef SMB_DEBUG
        fprintf(stderr, "Error sending negotiate protocol\n");
#endif
        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = -SMBlibE_SendFailed;     /* Failed, check lower
                                                 * layer errno */
        return (SMBlibE_BAD);
    }
    /* Now get the response ... */
    if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, alloc_len) < 0) {
#ifdef SMB_DEBUG
        fprintf(stderr, "Error receiving response to negotiate\n");
#endif
        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = -SMBlibE_RecvFailed;     /* Failed, check lower
                                                 * layer errno */
        return (SMBlibE_BAD);
    }
    if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {
        /* Process error */
#ifdef SMB_DEBUG
        fprintf(stderr, "SMB_Negotiate failed with errorclass = %i, Error Code = %i\n",
                CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
                SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
#endif
        SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_Remote;
        return SMBlibE_BAD;
    }
    if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) {
#ifdef SMB_DEBUG
        fprintf(stderr, "None of our protocols was accepted ... ");
#endif
        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_NegNoProt;
        return (SMBlibE_BAD);
    }
    /* Now, unpack the info from the response, if any and evaluate the
     * proto selected. We must make sure it is one we like... */
    Con_Handle->prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset);
    Con_Handle->protocol = SMB_Figure_Protocol(Prots, prot);

    if (Con_Handle->protocol == SMB_P_Unknown) {        /* No good ... */
        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_ProtUnknown;
        return SMBlibE_BAD;
    }
    switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) {
      case 0x01:                /* No more info ... */
          break;

      case 13:                  /* Up to and including LanMan 2.1 */
          Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset);
          Con_Handle->encrypt_passwords
              = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00);
          Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask;

          Con_Handle->max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset);
          Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset);
          Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset);
          Con_Handle->Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset);
          Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset);
          Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset);
          Con_Handle->Encrypt_Key_Len
              = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset);

          p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset);
#ifdef SMB_DEBUG
          fprintf(stderr, "%s",
                  (char *) (SMB_Hdr(pkt) + SMB_negrLM_buf_offset));
#endif
          memcpy(Con_Handle->Encrypt_Key, p, 8);

          p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset
                            + Con_Handle->Encrypt_Key_Len);

          strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1);
          break;

      case 17:                  /* NT LM 0.12 and LN LM 1.0 */
          Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset);
          Con_Handle->encrypt_passwords
              = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00);
          Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask;

          Con_Handle->max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset);
          Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset);
          Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset);
          Con_Handle->MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset);
          Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset);
          Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset);
          Con_Handle->Encrypt_Key_Len = CVAL(SMB_Hdr(pkt),
                                             SMB_negrNTLM_ekl_offset);

          p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset);
          memcpy(Con_Handle->Encrypt_Key, p, 8);
          p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset
                            + Con_Handle->Encrypt_Key_Len);

          strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1);
          break;

      default:
#ifdef SMB_DEBUG
          fprintf(stderr, "Unknown NegProt response format ... Ignored\n");
          fprintf(stderr, "  wct = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset));
#endif
          break;
    }

#ifdef SMB_DEBUG
    fprintf(stderr, "Protocol selected is: %i:%s\n", prot, Prots[prot]);
#endif

    RFCNB_Free_Pkt(pkt);
    return 0;
}
SMB_Tree_Handle
SMB_TreeConnect(SMB_Handle_Type Con_Handle,
    SMB_Tree_Handle Tree_Handle,
    char *path,
    char *password,
    const char *device)
{
    struct RFCNB_Pkt *pkt;
    int param_len, pkt_len;
    char *p;
    SMB_Tree_Handle tree;

    /* Figure out how much space is needed for path, password, dev ... */

    if ((path == NULL) | (password == NULL) | (device == NULL)) {

#ifdef DEBUG
	fprintf(stderr, "Bad parameter passed to SMB_TreeConnect\n");
#endif

	SMBlib_errno = SMBlibE_BadParam;
	return (NULL);

    }
    /* The + 2 is because of the \0 and the marker ...                    */

    param_len = strlen(path) + 2 + strlen(password) + 2 + strlen(device) + 2;

    /* The -1 accounts for the one byte smb_buf we have because some systems */
    /* don't like char msg_buf[]                                             */

    pkt_len = SMB_tcon_len + param_len;

    pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len);

    if (pkt == NULL) {

	SMBlib_errno = SMBlibE_NoSpace;
	return (NULL);		/* Should handle the error */

    }
    /* Now allocate a tree for this to go into ... */

    if (Tree_Handle == NULL) {

	tree = (SMB_Tree_Handle) malloc(sizeof(struct SMB_Tree_Structure));

	if (tree == NULL) {

	    RFCNB_Free_Pkt(pkt);
	    SMBlib_errno = SMBlibE_NoSpace;
	    return (NULL);

	}
    } else {

	tree = Tree_Handle;

    }

    tree->next = tree->prev = NULL;
    tree->con = Con_Handle;
    strncpy(tree->path, path, sizeof(tree->path));
    strncpy(tree->device_type, device, sizeof(tree->device_type));

    /* Now plug in the values ... */

    memset(SMB_Hdr(pkt), 0, SMB_tcon_len);
    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);	/* Plunk in IDF */
    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtcon;
    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid);
    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;

    SSVAL(SMB_Hdr(pkt), SMB_tcon_bcc_offset, param_len);

    /* Now copy the param strings in with the right stuff */

    p = (char *) (SMB_Hdr(pkt) + SMB_tcon_buf_offset);
    *p = SMBasciiID;
    strcpy(p + 1, path);
    p = p + strlen(path) + 2;
    *p = SMBasciiID;
    strcpy(p + 1, password);
    p = p + strlen(password) + 2;
    *p = SMBasciiID;
    strcpy(p + 1, device);

    /* Now send the packet and sit back ... */

    if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
	fprintf(stderr, "Error sending TCon request\n");
#endif

	if (Tree_Handle == NULL)
	    free(tree);
	RFCNB_Free_Pkt(pkt);
	SMBlib_errno = -SMBlibE_SendFailed;
	return (NULL);

    }
    /* Now get the response ... */

    if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
	fprintf(stderr, "Error receiving response to TCon\n");
#endif

	if (Tree_Handle == NULL)
	    free(tree);
	RFCNB_Free_Pkt(pkt);
	SMBlib_errno = -SMBlibE_RecvFailed;
	return (NULL);

    }
    /* Check out the response type ... */

    if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {	/* Process error */

#ifdef DEBUG
	fprintf(stderr, "SMB_TCon failed with errorclass = %i, Error Code = %i\n",
	    CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
	    SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
#endif

	if (Tree_Handle == NULL)
	    free(tree);
	SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
	RFCNB_Free_Pkt(pkt);
	SMBlib_errno = SMBlibE_Remote;
	return (NULL);

    }
    tree->tid = SVAL(SMB_Hdr(pkt), SMB_tconr_tid_offset);
    tree->mbs = SVAL(SMB_Hdr(pkt), SMB_tconr_mbs_offset);

#ifdef DEBUG
    fprintf(stderr, "TConn succeeded, with TID=%i, Max Xmit=%i\n",
	tree->tid, tree->mbs);
#endif

    /* Now link the Tree to the Server Structure ... */

    if (Con_Handle->first_tree == NULL) {

	Con_Handle->first_tree = tree;
	Con_Handle->last_tree = tree;

    } else {

	Con_Handle->last_tree->next = tree;
	tree->prev = Con_Handle->last_tree;
	Con_Handle->last_tree = tree;

    }

    RFCNB_Free_Pkt(pkt);
    return (tree);

}
Ejemplo n.º 4
0
int SMBapi_NetUserPasswordSet(SMB_Tree_Handle tree, char *user,
                              char *oldpass, char *newpass, int *apiStatus)

{
    struct RFCNB_Pkt *pkt;
    int param_len, i, pkt_len, pad_api_name = FALSE;
    char *p;

    /* Get a packet, we need one with space for a transact plus. The calc   */
    /* below lays it all out as it is, including the empty string after the */
    /* descriptor and before the username                                   */

    param_len = 2 + strlen(SMB_LMAPI_SUPW_DESC) + 1 +
                1 /* for empty string :-) */ + strlen(user) +
                1 + 16 + 16 + 2 + 2;

    /* We have no setup words, wo we don't account for them */

    pkt_len = SMB_trans_len + 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT) + 1;

    /* Pad things onto a word boundary ... */

    if (pkt_len & 0x0001) {
        pkt_len = pkt_len + 1;
        pad_api_name = TRUE;
    }

    pkt_len = pkt_len + param_len;

    /* Now allocate space for the packet, build it and send it */

    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);

    if (pkt == NULL) {

        SMBlib_errno = SMBlibE_NoSpace;
        return(SMBlibE_BAD); /* Should handle the error */

    }

    memset(SMB_Hdr(pkt), 0, SMB_trans_len);
    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtrans;
    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 14;

    SSVAL(SMB_Hdr(pkt), SMB_trans_tpc_offset, param_len);
    SSVAL(SMB_Hdr(pkt), SMB_trans_tdc_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_trans_mpc_offset, 4);
    SSVAL(SMB_Hdr(pkt), SMB_trans_mdc_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_trans_msc_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_trans_flg_offset, 0);
    SIVAL(SMB_Hdr(pkt), SMB_trans_tmo_offset, 5000);
    SSVAL(SMB_Hdr(pkt), SMB_trans_pbc_offset, param_len);
    SSVAL(SMB_Hdr(pkt), SMB_trans_pbo_offset, SMB_trans_len + 2 +
          strlen(SMB_LMAPI_SLOT) + 1);
    SSVAL(SMB_Hdr(pkt), SMB_trans_dbc_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_trans_dbo_offset, 0);

    /* Now put in the bcc and the rest of the info ... */

    SSVAL(SMB_Hdr(pkt), SMB_trans_len, param_len + strlen(SMB_LMAPI_SLOT) + 1);

    p = SMB_Hdr(pkt) + SMB_trans_len + 2;  /* Skip the BCC and ect */

    strcpy(p, SMB_LMAPI_SLOT);
    p = p + strlen(SMB_LMAPI_SLOT) + 1;

    if (pad_api_name == TRUE)   /* Pad if we need to */
        p = p + 1;

    /*  SSVAL(p, 0, 65000);  /* Check the result */
    SSVAL(p, 0, SMB_LMapi_UserPasswordSet);  /* The api call */

    p = p + 2;

    strcpy(p, SMB_LMAPI_SUPW_DESC);          /* Copy in the param desc */

    p = p + strlen(SMB_LMAPI_SUPW_DESC) + 1;

    *p = 0;                                  /* Stick in that null string */
    p = p + 1;

    strcpy(p, user);

    p = p + strlen(user) + 1;

    strncpy(p, oldpass, 16);

    p = p + 16;

    strncpy(p, newpass, 16);

    p = p + 16;

    SSVAL(p, 0, 0);                 /* Seems to be zero always? */
    SSVAL(p, 2, strlen(newpass));   /* Length of new password ...*/

    /* Now send the lot and get a response ... */

    if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
        fprintf(stderr, "Error sending Trans request\n");
#endif

        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_SendFailed;
        return(SMBlibE_BAD);

    }

    /* Now get the response ... */

    if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
        fprintf(stderr, "Error receiving response to Trans request\n");
#endif

        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_RecvFailed;
        return(SMBlibE_BAD);

    }

    /* Check out the response type ... */

    if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */

#ifdef DEBUG
        fprintf(stderr, "SMB_trans failed with errorclass = %i, Error Code = %i\n",
                CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
                SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
#endif

        SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_Remote;
        return(SMBlibE_BAD);

    }

    /* All ok, pass back the status */

    *apiStatus = SVAL(SMB_Hdr(pkt), SVAL(SMB_Hdr(pkt), SMB_transr_pbo_offset));
    RFCNB_Free_Pkt(pkt);

    return(0);

}
Ejemplo n.º 5
0
int SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle, char *UserName,
                       char *PassWord,
                       char *service,
                       char *service_type)

{
    struct RFCNB_Pkt *pkt;
    int param_len, i, pkt_len, andx_len, andx_param_len;
    char *p, *AndXCom;

    /* First we need a packet etc ... but we need to know what protocol has  */
    /* been negotiated to figure out if we can do it and what SMB format to  */
    /* use ...                                                               */

    /* Since we are going to do a LogonAndX with a TCon as the second command*/
    /* We need the packet size correct. So TCon starts at wct field          */

    if (SMB_Types[Con_Handle -> protocol] < SMB_P_LanMan1) {

        SMBlib_errno = SMBlibE_ProtLow;
        return(SMBlibE_BAD);

    }

    /* Now build the correct structure */

    if (SMB_Types[Con_Handle -> protocol] < SMB_P_NT1) {

        param_len = strlen(UserName) + 1 + strlen(PassWord) +
                    strlen(Con_Handle -> PDomain) + 1 +
                    strlen(Con_Handle -> OSName) + 1;

        pkt_len = SMB_ssetpLM_len + param_len;

        pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);

        if (pkt == NULL) {

            SMBlib_errno = SMBlibE_NoSpace;
            return(SMBlibE_BAD); /* Should handle the error */

        }

        memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len);
        SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
        *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
        SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
        SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
        SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
        SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
        *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
        *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
        SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);

        SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
        SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, strlen(PassWord));
        SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);

        /* Now copy the param strings in with the right stuff */

        p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);

        /* Copy  in password, then the rest. Password has no null at end */

        strcpy(p, PassWord);

        p = p + strlen(PassWord);

        strcpy(p, UserName);
        p = p + strlen(UserName);
        *p = 0;

        p = p + 1;

        strcpy(p, Con_Handle -> PDomain);
        p = p + strlen(Con_Handle -> PDomain);
        *p = 0;
        p = p + 1;

        strcpy(p, Con_Handle -> OSName);
        p = p + strlen(Con_Handle -> OSName);
        *p = 0;

    } else {

        /* We don't admit to UNICODE support ... */

        param_len = strlen(UserName) + 1 + strlen(PassWord) +
                    strlen(Con_Handle -> PDomain) + 1 +
                    strlen(Con_Handle -> OSName) + 1;

        andx_len = SMB_tcon_len - SMB_hdr_wct_offset;

        /* We send a null password as we sent one in the setup and X */

        andx_param_len = strlen(service) + 2 + 2 + strlen(service_type) + 2;

        pkt_len = SMB_ssetpNTLM_len + param_len + andx_len + andx_param_len;

        pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);

        if (pkt == NULL) {

            SMBlib_errno = SMBlibE_NoSpace;
            return(-1); /* Should handle the error */

        }

        memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len);
        SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
        *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
        SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
        SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
        SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
        SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
        *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
        *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtcon;
        SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpNTLM_len + param_len);

        SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 2);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
        SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, strlen(PassWord));
        SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
        SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
        SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
        SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);

        /* Now copy the param strings in with the right stuff */

        p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);

        /* Copy  in password, then the rest. Password has no null at end */

        strcpy(p, PassWord);

        p = p + strlen(PassWord);

        strcpy(p, UserName);
        p = p + strlen(UserName);
        *p = 0;

        p = p + 1;

        strcpy(p, Con_Handle -> PDomain);
        p = p + strlen(Con_Handle -> PDomain);
        *p = 0;
        p = p + 1;

        strcpy(p, Con_Handle -> OSName);
        p = p + strlen(Con_Handle -> OSName);
        *p = 0;

        /* Now set up the TCON Part ... from WCT, make up a pointer that will
           help us ...                                                        */

        AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset;

        *(AndXCom + SMB_hdr_wct_offset) = 0;   /* No Words */

        SSVAL(AndXCom, SMB_tcon_bcc_offset, andx_param_len);

        p = (char *)(AndXCom + SMB_tcon_buf_offset);

        *p = SMBasciiID;
        strcpy(p + 1, service);
        p = p + strlen(service) + 2;
        *p = SMBasciiID;                    /* No password ... */
        *(p + 1) = 0;
        p = p + 2;
        *p = SMBasciiID;
        strcpy(p + 1, service_type);

    }

    /* Now send it and get a response */

    if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
        fprintf(stderr, "Error sending SessSetupAndTCon request\n");
#endif

        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_SendFailed;
        return(SMBlibE_BAD);

    }

    /* Now get the response ... */

    if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
        fprintf(stderr, "Error receiving response to SessSetupAndTCon\n");
#endif

        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_RecvFailed;
        return(SMBlibE_BAD);

    }

    /* Check out the response type ... */

    if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */

#ifdef DEBUG
        fprintf(stderr, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n",
                CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
                SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
#endif

        /* Note, here, that we have not properly handled the error processing */
        /* and so we cannot tell how much of our request crapped out          */

        SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
        RFCNB_Free_Pkt(pkt);
        SMBlib_errno = SMBlibE_Remote;
        return(SMBlibE_BAD);

    }

#ifdef DEBUG
    fprintf(stderr, "SessSetupAndX response. Action = %i\n",
            SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
#endif

    /* Now pick up the UID for future reference ... */

    Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);

    /* And pick up the TID as well, which will be at offset 4? from wct */

    AndXCom = (char *)SMB_Hdr(pkt) + SVAL(SMB_Hdr(pkt), SMB_ssetpr_axo_offset);

    Con_Handle -> tid = SVAL(AndXCom, 3);        /* Naughty   */
    Con_Handle -> max_xmit = SVAL(AndXCom, 1);   /* And Again */

    RFCNB_Free_Pkt(pkt);

    return(0);

}