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); }
/* 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); }
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); }
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); }