diff options
-rw-r--r-- | source3/include/proto.h | 21 | ||||
-rw-r--r-- | source3/libsmb/cli_spoolss.c | 100 | ||||
-rw-r--r-- | source3/libsmb/clifile.c | 53 | ||||
-rw-r--r-- | source3/libsmb/clisecdesc.c | 17 | ||||
-rw-r--r-- | source3/libsmb/smbencrypt.c | 80 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 12 |
6 files changed, 215 insertions, 68 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index a02349a075..a53dab7f71 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -832,8 +832,19 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, PRINTER_INFO_CTR *ctr); uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, int *returned, PORT_INFO_CTR *ctr); -uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, - uint32 level, PRINTER_INFO_CTR *ctr); +uint32 cli_spoolss_getprinter( + struct cli_state *cli, + POLICY_HND *pol, + uint32 level, + PRINTER_INFO_CTR *ctr +); +uint32 cli_spoolss_setprinter( + struct cli_state *cli, + POLICY_HND *pol, + uint32 level, + PRINTER_INFO_CTR *ctr, + uint32 command +); uint32 cli_spoolss_getprinterdriver ( struct cli_state *cli, POLICY_HND *pol, @@ -947,6 +958,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); BOOL cli_chkpath(struct cli_state *cli, char *path); BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path); /*The following definitions come from libsmb/clilist.c */ @@ -1152,8 +1164,9 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); -BOOL decode_pw_buffer(char buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len); +BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len, + uchar nt_p16[16], uchar p16[16]); /*The following definitions come from libsmb/smberr.c */ diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 475ebf66a2..db761e57bf 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -529,8 +529,12 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, } /* Get printer info */ -uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, - uint32 level, PRINTER_INFO_CTR *ctr) +uint32 cli_spoolss_getprinter( + struct cli_state *cli, + POLICY_HND *pol, + uint32 level, + PRINTER_INFO_CTR *ctr +) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTER q; @@ -550,14 +554,12 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - make_spoolss_q_getprinter(&q, pol, level, &buffer, - needed); + make_spoolss_q_getprinter(&q, pol, level, &buffer, needed); /* Marshall data and send request */ - if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, - &rbuf)) { + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf)) + { result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -568,25 +570,20 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, } /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { switch (level) { case 0: - decode_printer_info_0(r.buffer, 1, - &ctr->printers_0); + decode_printer_info_0(r.buffer, 1, &ctr->printers_0); break; case 1: - decode_printer_info_1(r.buffer, 1, - &ctr->printers_1); + decode_printer_info_1(r.buffer, 1, &ctr->printers_1); break; case 2: - decode_printer_info_2(r.buffer, 1, - &ctr->printers_2); + decode_printer_info_2(r.buffer, 1, &ctr->printers_2); break; case 3: - decode_printer_info_3(r.buffer, 1, - &ctr->printers_3); + decode_printer_info_3(r.buffer, 1, &ctr->printers_3); break; } } @@ -601,6 +598,57 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, } /********************************************************************** + * Set printer info + */ +uint32 cli_spoolss_setprinter( + struct cli_state *cli, + POLICY_HND *pol, + uint32 level, + PRINTER_INFO_CTR *ctr, + uint32 command +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTER q; + SPOOL_R_SETPRINTER r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + make_spoolss_q_setprinter(&q, pol, level, ctr, command); + + /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) + { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) + { + goto done; + } + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + + return result; +} + +/********************************************************************** * Get installed printer drivers for a given printer */ uint32 cli_spoolss_getprinterdriver ( @@ -860,22 +908,28 @@ uint32 cli_spoolss_addprinterdriver ( make_spoolss_q_addprinterdriver (&q, server, level, ctr); /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Return output parameters */ result = r.status; +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } @@ -915,22 +969,28 @@ uint32 cli_spoolss_addprinterex ( make_spoolss_q_addprinterex (&q, server, client, user, level, ctr); /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Return output parameters */ result = r.status; +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d62a0a417a..c2db97cb3e 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -510,10 +510,8 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, p = smb_buf(cli->outbuf); SIVAL(p, 0, cli->pid); - SIVAL(p, 4, (offset>>32)); - SIVAL(p, 8, (offset&0xffffffff)); - SIVAL(p, 12, (len>>32)); - SIVAL(p, 16, (len&0xffffffff)); + SOFF_T_R(p, 4, offset); + SOFF_T_R(p, 12, len); p += 20; cli_setup_bcc(cli, p); @@ -560,10 +558,8 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ p = smb_buf(cli->outbuf); SIVAL(p, 0, cli->pid); - SIVAL(p, 4, (offset>>32)); - SIVAL(p, 8, (offset&0xffffffff)); - SIVAL(p, 12, (len>>32)); - SIVAL(p, 16, (len&0xffffffff)); + SOFF_T_R(p, 4, offset); + SOFF_T_R(p, 12, len); p += 20; cli_setup_bcc(cli, p); cli_send_smb(cli); @@ -779,3 +775,44 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } + +/**************************************************************************** +create and open a temporary file +****************************************************************************/ +int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,1,strlen(path)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBctemp; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0); + + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, path, -1, STR_TERMINATE | STR_CONVERT); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + if (tmp_path) { + pstring path2; + clistr_pull(cli, path2, smb_buf(cli->inbuf)+1, + sizeof(path2), -1, STR_TERMINATE | STR_CONVERT); + *tmp_path = strdup(path2); + } + + return SVAL(cli->inbuf,smb_vwv0); +} diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index d34a23537a..0b52d62513 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -33,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx = NULL; + TALLOC_CTX *mem_ctx; prs_struct pd; SEC_DESC *psd = NULL; @@ -74,13 +74,11 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) cleanup: - if (mem_ctx) { - talloc_destroy(mem_ctx); - prs_mem_free(&pd); - } + talloc_destroy(mem_ctx); safe_free(rparam); safe_free(rdata); + prs_mem_free(&pd); return psd; } @@ -95,7 +93,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx=NULL; + TALLOC_CTX *mem_ctx; prs_struct pd; BOOL ret = False; @@ -140,10 +138,9 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) safe_free(rparam); safe_free(rdata); - if (mem_ctx) { - talloc_destroy(mem_ctx); - prs_mem_free(&pd); - } + talloc_destroy(mem_ctx); + + prs_mem_free(&pd); return ret; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 858045dc02..caf9256787 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -231,11 +231,18 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ /*********************************************************** decode a password buffer ************************************************************/ -BOOL decode_pw_buffer(char buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len) +BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len, + uchar nt_p16[16], uchar p16[16]) { - int uni_pw_len=0; char *pw; + + int uni_pw_len=0; + int byte_len=0; + char unicode_passwd[514]; + char lm_ascii_passwd[514]; + char passwd[514]; + /* Warning !!! : This function is called from some rpc call. The password IN the buffer is a UNICODE string. @@ -243,33 +250,72 @@ BOOL decode_pw_buffer(char buffer[516], char *new_pwrd, If you reuse that code somewhere else check first. */ - ZERO_STRUCTP(new_pwrd); + ZERO_STRUCT(unicode_passwd); + ZERO_STRUCT(lm_ascii_passwd); + ZERO_STRUCT(passwd); - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ + memset(nt_p16, '\0', 16); + memset(p16, '\0', 16); - *new_pw_len = IVAL(buffer, 512); + /* The length of the new password is in the last 4 bytes of the data buffer. */ + + byte_len = IVAL(in_buffer, 512); #ifdef DEBUG_PASSWORD - dump_data(100, buffer, 516); + dump_data(100, in_buffer, 516); #endif - if (((int)*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) { - DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", (*new_pw_len))); + /* Password cannot be longer than 128 characters */ + if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { + DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); return False; } + + uni_pw_len = byte_len/2; + pw = dos_unistrn2((uint16 *)(&in_buffer[512 - byte_len]), byte_len); + memcpy(passwd, pw, uni_pw_len); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: passwd: ")); + dump_data(100, (char *)passwd, uni_pw_len); + DEBUG(100,("len:%d\n", uni_pw_len)); +#endif + memcpy(unicode_passwd, &in_buffer[512 - byte_len], byte_len); + + mdfour(nt_p16, (unsigned char *)unicode_passwd, byte_len); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: nt#:")); + dump_data(100, (char *)nt_p16, 16); + DEBUG(100,("\n")); +#endif + + /* Mangle the passwords into Lanman format */ + memcpy(lm_ascii_passwd, passwd, uni_pw_len); + lm_ascii_passwd[14] = '\0'; + strupper(lm_ascii_passwd); - uni_pw_len = *new_pw_len; - *new_pw_len /= 2; - pw = dos_unistrn2((uint16 *)(&buffer[512 - uni_pw_len]), uni_pw_len); - memcpy(new_pwrd, pw, *new_pw_len); + /* Calculate the SMB (lanman) hash functions of the password */ + E_P16((uchar *) lm_ascii_passwd, (uchar *)p16); #ifdef DEBUG_PASSWORD - dump_data(100, new_pwrd, (*new_pw_len)); + DEBUG(100,("nt_lm_owf_gen: lm#:")); + dump_data(100, (char *)p16, 16); + DEBUG(100,("\n")); #endif + /* copy the password and it's length to the return buffer */ + *new_pw_len=uni_pw_len; + memcpy(new_pwrd, passwd, uni_pw_len); + new_pwrd[uni_pw_len]='\0'; + + + /* clear out local copy of user's password (just being paranoid). */ + ZERO_STRUCT(unicode_passwd); + ZERO_STRUCT(lm_ascii_passwd); + ZERO_STRUCT(passwd); + return True; + } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 9e9c5d950e..e0d6d6056e 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2104,11 +2104,9 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid) copy_sam_passwd(&new_pwd, pwd); copy_id23_to_sam_passwd(&new_pwd, id23); - if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len)) + if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) return False; - - nt_lm_owf_gen(buf, nt_hash, lm_hash); - + pdb_set_lanman_passwd (&new_pwd, lm_hash); pdb_set_nt_passwd (&new_pwd, nt_hash); @@ -2153,13 +2151,9 @@ static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid) memset(buf, 0, sizeof(buf)); - if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len)) + if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len, nt_hash, lm_hash)) return False; - DEBUG(5,("set_user_info_24:nt_lm_owf_gen\n")); - - nt_lm_owf_gen(buf, nt_hash, lm_hash); - pdb_set_lanman_passwd (pwd, lm_hash); pdb_set_nt_passwd (pwd, nt_hash); |