2 /* UNIX SMBlib NetBIOS implementation
7 Copyright (C) Richard Sharpe 1996
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "smblib/smblib-priv.h"
28 #include "rfcnb/rfcnb.h"
34 SMB_Tree_Handle SMBapi_Tree
= NULL
;
36 /* Send an api request to the \\server\IPC$ tree, with a \PIPE\LANMAN api */
37 /* request to change the user's password */
39 #define SMB_LMAPI_SLOT "\\PIPE\\LANMAN"
40 #define SMB_LMAPI_SUPW_DESC "zb16b16WW"
42 int SMBapi_NetUserPasswordSet(SMB_Tree_Handle tree
, char *user
,
43 char *oldpass
, char *newpass
, int *apiStatus
)
46 struct RFCNB_Pkt
*pkt
;
47 int param_len
, i
, pkt_len
, pad_api_name
= FALSE
;
50 /* Get a packet, we need one with space for a transact plus. The calc */
51 /* below lays it all out as it is, including the empty string after the */
52 /* descriptor and before the username */
54 param_len
= 2 + strlen(SMB_LMAPI_SUPW_DESC
) + 1 +
55 1 /* for empty string :-) */ + strlen(user
) +
58 /* We have no setup words, wo we don't account for them */
60 pkt_len
= SMB_trans_len
+ 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT
) + 1;
62 /* Pad things onto a word boundary ... */
64 if (pkt_len
& 0x0001) {
65 pkt_len
= pkt_len
+ 1;
70 pkt_len
= pkt_len
+ param_len
;
72 /* Now allocate space for the packet, build it and send it */
74 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
78 SMBlib_errno
= SMBlibE_NoSpace
;
79 return(SMBlibE_BAD
); /* Should handle the error */
83 memset(SMB_Hdr(pkt
), 0, SMB_trans_len
);
84 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
85 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBtrans
;
86 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, tree
-> con
-> pid
);
87 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, tree
-> tid
);
88 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, tree
-> con
-> mid
);
89 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, tree
-> con
-> uid
);
90 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 14;
92 SSVAL(SMB_Hdr(pkt
), SMB_trans_tpc_offset
, param_len
);
93 SSVAL(SMB_Hdr(pkt
), SMB_trans_tdc_offset
, 0);
94 SSVAL(SMB_Hdr(pkt
), SMB_trans_mpc_offset
, 4);
95 SSVAL(SMB_Hdr(pkt
), SMB_trans_mdc_offset
, 0);
96 SSVAL(SMB_Hdr(pkt
), SMB_trans_msc_offset
, 0);
97 SSVAL(SMB_Hdr(pkt
), SMB_trans_flg_offset
, 0);
98 SIVAL(SMB_Hdr(pkt
), SMB_trans_tmo_offset
, 5000);
99 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbc_offset
, param_len
);
100 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbo_offset
, SMB_trans_len
+ 2 +
101 strlen(SMB_LMAPI_SLOT
) + 1);
102 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbc_offset
, 0);
103 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbo_offset
, 0);
105 /* Now put in the bcc and the rest of the info ... */
107 SSVAL(SMB_Hdr(pkt
), SMB_trans_len
, param_len
+ strlen(SMB_LMAPI_SLOT
) + 1);
109 p
= SMB_Hdr(pkt
) + SMB_trans_len
+ 2; /* Skip the BCC and ect */
111 strcpy(p
, SMB_LMAPI_SLOT
);
112 p
= p
+ strlen(SMB_LMAPI_SLOT
) + 1;
114 if (pad_api_name
== TRUE
) /* Pad if we need to */
117 /* SSVAL(p, 0, 65000); /* Check the result */
118 SSVAL(p
, 0, SMB_LMapi_UserPasswordSet
); /* The api call */
122 strcpy(p
, SMB_LMAPI_SUPW_DESC
); /* Copy in the param desc */
124 p
= p
+ strlen(SMB_LMAPI_SUPW_DESC
) + 1;
126 *p
= 0; /* Stick in that null string */
131 p
= p
+ strlen(user
) + 1;
133 strncpy(p
, oldpass
, 16);
137 strncpy(p
, newpass
, 16);
141 SSVAL(p
, 0, 0); /* Seems to be zero always? */
142 SSVAL(p
, 2, strlen(newpass
)); /* Length of new password ...*/
144 /* Now send the lot and get a response ... */
146 if (RFCNB_Send(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
149 fprintf(stderr
, "Error sending Trans request\n");
153 SMBlib_errno
= SMBlibE_SendFailed
;
158 /* Now get the response ... */
160 if (RFCNB_Recv(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
163 fprintf(stderr
, "Error receiving response to Trans request\n");
167 SMBlib_errno
= SMBlibE_RecvFailed
;
172 /* Check out the response type ... */
174 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
177 fprintf(stderr
, "SMB_trans failed with errorclass = %i, Error Code = %i\n",
178 CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
),
179 SVAL(SMB_Hdr(pkt
), SMB_hdr_err_offset
));
182 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
184 SMBlib_errno
= SMBlibE_Remote
;
189 /* All ok, pass back the status */
191 *apiStatus
= SVAL(SMB_Hdr(pkt
), SVAL(SMB_Hdr(pkt
), SMB_transr_pbo_offset
));
198 #define SMB_LMAPI_SUI_DESC "zWsTPWW"
199 #define SMB_LMAPI_SUI_DATA_DESC "B16"
202 /* Set user info ... specifically, password */
204 int SMBapi_NetSetUserInfo(SMB_Tree_Handle tree
, char *user
,
205 char *newpass
, int *apiStatus
)
208 struct RFCNB_Pkt
*pkt
;
209 int param_len
, i
, pkt_len
, data_len
, pad_api_name
= FALSE
;
210 int pad_params
= FALSE
;
213 /* Get a packet, we need one with space for a transact plus. The calc */
214 /* below lays it all out as it is, including the empty string after the */
215 /* descriptor and before the username */
217 param_len
= 2 + strlen(SMB_LMAPI_SUI_DESC
) + 1 +
218 + strlen(SMB_LMAPI_SUI_DATA_DESC
) + 1 + strlen(user
) +
223 /* We have no setup words, so we don't account for them */
225 pkt_len
= SMB_trans_len
+ 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT
) + 1;
227 if (pkt_len
& 0x0001) { /* Pad to a WORD boundary */
233 if (param_len
& 0x0001) { /* pad to a WORD boundary */
239 pkt_len
= pkt_len
+ param_len
+ data_len
;
241 if (pad_api_name
== TRUE
) pkt_len
= pkt_len
+ 1;
242 if (pad_params
== TRUE
) pkt_len
= pkt_len
+ 1;
244 /* Now allocate space for the packet, build it and send it */
246 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
250 SMBlib_errno
= SMBlibE_NoSpace
;
251 return(SMBlibE_BAD
); /* Should handle the error */
255 memset(SMB_Hdr(pkt
), 0, SMB_trans_len
);
256 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
257 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBtrans
;
258 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, tree
-> con
-> pid
);
259 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, tree
-> tid
);
260 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, tree
-> con
-> mid
);
261 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, tree
-> con
-> uid
);
262 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 14;
264 SSVAL(SMB_Hdr(pkt
), SMB_trans_tpc_offset
, param_len
);
265 SSVAL(SMB_Hdr(pkt
), SMB_trans_tdc_offset
, data_len
);
266 SSVAL(SMB_Hdr(pkt
), SMB_trans_mpc_offset
, 4);
267 SSVAL(SMB_Hdr(pkt
), SMB_trans_mdc_offset
, 0);
268 SSVAL(SMB_Hdr(pkt
), SMB_trans_msc_offset
, 0);
269 SSVAL(SMB_Hdr(pkt
), SMB_trans_flg_offset
, 0);
270 SIVAL(SMB_Hdr(pkt
), SMB_trans_tmo_offset
, 5000);
271 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbc_offset
, param_len
);
272 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbo_offset
, SMB_trans_len
+ 2 +
273 strlen(SMB_LMAPI_SLOT
) + 1);
274 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbc_offset
, data_len
);
275 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbo_offset
, pkt_len
- data_len
);
277 /* Now put in the bcc and the rest of the info ... */
279 SSVAL(SMB_Hdr(pkt
), SMB_trans_len
, param_len
+ strlen(SMB_LMAPI_SLOT
) +
282 p
= SMB_Hdr(pkt
) + SMB_trans_len
+ 2; /* Skip the BCC and ect */
284 strcpy(p
, SMB_LMAPI_SLOT
);
285 p
= p
+ strlen(SMB_LMAPI_SLOT
) + 1;
287 if (pad_api_name
== TRUE
) /* Pad to a word boundary */
290 /* SSVAL(p, 0, 65000); /* Check the result */
291 SSVAL(p
, 0, SMB_LMapi_SetUserInfo
); /* The api call */
295 strcpy(p
, SMB_LMAPI_SUI_DESC
); /* Copy in the param desc */
297 p
= p
+ strlen(SMB_LMAPI_SUI_DESC
) + 1;
299 strcpy(p
, SMB_LMAPI_SUI_DATA_DESC
); /* Copy in second descriptor */
301 p
= p
+ strlen(SMB_LMAPI_SUI_DATA_DESC
) + 1;
305 p
= p
+ strlen(user
) + 1;
307 SSVAL(p
, 0, 1); /* Claim that we have a level 1 struct ? */
311 SSVAL(p
, 0, 3); /* Set the password */
312 SSVAL(p
, 2, 1); /* Seems to be one ... */
313 SSVAL(p
, 4, strlen(newpass
)); /* Length of new password ...*/
315 /* Now copy the data in ... */
319 if (pad_params
== TRUE
)
324 /* Now send the lot and get a response ... */
326 if (RFCNB_Send(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
329 fprintf(stderr
, "Error sending Trans SetUserInfo request\n");
333 SMBlib_errno
= SMBlibE_SendFailed
;
338 /* Now get the response ... */
340 if (RFCNB_Recv(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
343 fprintf(stderr
, "Error receiving response to Trans SetUserInfo request\n");
347 SMBlib_errno
= SMBlibE_RecvFailed
;
352 /* Check out the response type ... */
354 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
357 fprintf(stderr
, "SMB_trans SetUserInfo failed with errorclass = %i, Error Code = %i\n",
358 CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
),
359 SVAL(SMB_Hdr(pkt
), SMB_hdr_err_offset
));
362 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
364 SMBlib_errno
= SMBlibE_Remote
;
369 /* All ok, pass back the status */
371 *apiStatus
= SVAL(SMB_Hdr(pkt
), SVAL(SMB_Hdr(pkt
), SMB_transr_pbo_offset
));
378 /* List all the shares available on a server */
380 int SMBapi_NetShareEnum(SMB_Tree_Handle tree
, char *enum_buf
, int bufsiz
,
381 int *shares_returned
, int *shares_total
)