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 "rfcnb/rfcnb.h"
28 #include "smblib/smblib-priv.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;
69 pkt_len
= pkt_len
+ param_len
;
71 /* Now allocate space for the packet, build it and send it */
73 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
77 SMBlib_errno
= SMBlibE_NoSpace
;
78 return(SMBlibE_BAD
); /* Should handle the error */
82 memset(SMB_Hdr(pkt
), 0, SMB_trans_len
);
83 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
84 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBtrans
;
85 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, tree
-> con
-> pid
);
86 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, tree
-> tid
);
87 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, tree
-> con
-> mid
);
88 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, tree
-> con
-> uid
);
89 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 14;
91 SSVAL(SMB_Hdr(pkt
), SMB_trans_tpc_offset
, param_len
);
92 SSVAL(SMB_Hdr(pkt
), SMB_trans_tdc_offset
, 0);
93 SSVAL(SMB_Hdr(pkt
), SMB_trans_mpc_offset
, 4);
94 SSVAL(SMB_Hdr(pkt
), SMB_trans_mdc_offset
, 0);
95 SSVAL(SMB_Hdr(pkt
), SMB_trans_msc_offset
, 0);
96 SSVAL(SMB_Hdr(pkt
), SMB_trans_flg_offset
, 0);
97 SIVAL(SMB_Hdr(pkt
), SMB_trans_tmo_offset
, 5000);
98 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbc_offset
, param_len
);
99 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbo_offset
, SMB_trans_len
+ 2 +
100 strlen(SMB_LMAPI_SLOT
) + 1);
101 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbc_offset
, 0);
102 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbo_offset
, 0);
104 /* Now put in the bcc and the rest of the info ... */
106 SSVAL(SMB_Hdr(pkt
), SMB_trans_len
, param_len
+ strlen(SMB_LMAPI_SLOT
) + 1);
108 p
= SMB_Hdr(pkt
) + SMB_trans_len
+ 2; /* Skip the BCC and ect */
110 strcpy(p
, SMB_LMAPI_SLOT
);
111 p
= p
+ strlen(SMB_LMAPI_SLOT
) + 1;
113 if (pad_api_name
== TRUE
) /* Pad if we need to */
116 /* SSVAL(p, 0, 65000); /* Check the result */
117 SSVAL(p
, 0, SMB_LMapi_UserPasswordSet
); /* The api call */
121 strcpy(p
, SMB_LMAPI_SUPW_DESC
); /* Copy in the param desc */
123 p
= p
+ strlen(SMB_LMAPI_SUPW_DESC
) + 1;
125 *p
= 0; /* Stick in that null string */
130 p
= p
+ strlen(user
) + 1;
132 strncpy(p
, oldpass
, 16);
136 strncpy(p
, newpass
, 16);
140 SSVAL(p
, 0, 0); /* Seems to be zero always? */
141 SSVAL(p
, 2, strlen(newpass
)); /* Length of new password ...*/
143 /* Now send the lot and get a response ... */
145 if (RFCNB_Send(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
148 fprintf(stderr
, "Error sending Trans request\n");
152 SMBlib_errno
= SMBlibE_SendFailed
;
157 /* Now get the response ... */
159 if (RFCNB_Recv(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
162 fprintf(stderr
, "Error receiving response to Trans request\n");
166 SMBlib_errno
= SMBlibE_RecvFailed
;
171 /* Check out the response type ... */
173 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
176 fprintf(stderr
, "SMB_trans failed with errorclass = %i, Error Code = %i\n",
177 CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
),
178 SVAL(SMB_Hdr(pkt
), SMB_hdr_err_offset
));
181 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
183 SMBlib_errno
= SMBlibE_Remote
;
188 /* All ok, pass back the status */
190 *apiStatus
= SVAL(SMB_Hdr(pkt
), SVAL(SMB_Hdr(pkt
), SMB_transr_pbo_offset
));
197 #define SMB_LMAPI_SUI_DESC "zWsTPWW"
198 #define SMB_LMAPI_SUI_DATA_DESC "B16"
200 /* Set user info ... specifically, password */
202 int SMBapi_NetSetUserInfo(SMB_Tree_Handle tree
, char *user
,
203 char *newpass
, int *apiStatus
)
206 struct RFCNB_Pkt
*pkt
;
207 int param_len
, i
, pkt_len
, data_len
, pad_api_name
= FALSE
;
208 int pad_params
= FALSE
;
211 /* Get a packet, we need one with space for a transact plus. The calc */
212 /* below lays it all out as it is, including the empty string after the */
213 /* descriptor and before the username */
215 param_len
= 2 + strlen(SMB_LMAPI_SUI_DESC
) + 1 +
216 + strlen(SMB_LMAPI_SUI_DATA_DESC
) + 1 + strlen(user
) +
221 /* We have no setup words, so we don't account for them */
223 pkt_len
= SMB_trans_len
+ 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT
) + 1;
225 if (pkt_len
& 0x0001) { /* Pad to a WORD boundary */
231 if (param_len
& 0x0001) { /* pad to a WORD boundary */
237 pkt_len
= pkt_len
+ param_len
+ data_len
;
239 if (pad_api_name
== TRUE
) pkt_len
= pkt_len
+ 1;
240 if (pad_params
== TRUE
) pkt_len
= pkt_len
+ 1;
242 /* Now allocate space for the packet, build it and send it */
244 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
248 SMBlib_errno
= SMBlibE_NoSpace
;
249 return(SMBlibE_BAD
); /* Should handle the error */
253 memset(SMB_Hdr(pkt
), 0, SMB_trans_len
);
254 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
255 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBtrans
;
256 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, tree
-> con
-> pid
);
257 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, tree
-> tid
);
258 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, tree
-> con
-> mid
);
259 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, tree
-> con
-> uid
);
260 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 14;
262 SSVAL(SMB_Hdr(pkt
), SMB_trans_tpc_offset
, param_len
);
263 SSVAL(SMB_Hdr(pkt
), SMB_trans_tdc_offset
, data_len
);
264 SSVAL(SMB_Hdr(pkt
), SMB_trans_mpc_offset
, 4);
265 SSVAL(SMB_Hdr(pkt
), SMB_trans_mdc_offset
, 0);
266 SSVAL(SMB_Hdr(pkt
), SMB_trans_msc_offset
, 0);
267 SSVAL(SMB_Hdr(pkt
), SMB_trans_flg_offset
, 0);
268 SIVAL(SMB_Hdr(pkt
), SMB_trans_tmo_offset
, 5000);
269 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbc_offset
, param_len
);
270 SSVAL(SMB_Hdr(pkt
), SMB_trans_pbo_offset
, SMB_trans_len
+ 2 +
271 strlen(SMB_LMAPI_SLOT
) + 1);
272 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbc_offset
, data_len
);
273 SSVAL(SMB_Hdr(pkt
), SMB_trans_dbo_offset
, pkt_len
- data_len
);
275 /* Now put in the bcc and the rest of the info ... */
277 SSVAL(SMB_Hdr(pkt
), SMB_trans_len
, param_len
+ strlen(SMB_LMAPI_SLOT
) +
280 p
= SMB_Hdr(pkt
) + SMB_trans_len
+ 2; /* Skip the BCC and ect */
282 strcpy(p
, SMB_LMAPI_SLOT
);
283 p
= p
+ strlen(SMB_LMAPI_SLOT
) + 1;
285 if (pad_api_name
== TRUE
) /* Pad to a word boundary */
288 /* SSVAL(p, 0, 65000); /* Check the result */
289 SSVAL(p
, 0, SMB_LMapi_SetUserInfo
); /* The api call */
293 strcpy(p
, SMB_LMAPI_SUI_DESC
); /* Copy in the param desc */
295 p
= p
+ strlen(SMB_LMAPI_SUI_DESC
) + 1;
297 strcpy(p
, SMB_LMAPI_SUI_DATA_DESC
); /* Copy in second descriptor */
299 p
= p
+ strlen(SMB_LMAPI_SUI_DATA_DESC
) + 1;
303 p
= p
+ strlen(user
) + 1;
305 SSVAL(p
, 0, 1); /* Claim that we have a level 1 struct ? */
309 SSVAL(p
, 0, 3); /* Set the password */
310 SSVAL(p
, 2, 1); /* Seems to be one ... */
311 SSVAL(p
, 4, strlen(newpass
)); /* Length of new password ...*/
313 /* Now copy the data in ... */
317 if (pad_params
== TRUE
)
322 /* Now send the lot and get a response ... */
324 if (RFCNB_Send(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
327 fprintf(stderr
, "Error sending Trans SetUserInfo request\n");
331 SMBlib_errno
= SMBlibE_SendFailed
;
336 /* Now get the response ... */
338 if (RFCNB_Recv(tree
-> con
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
341 fprintf(stderr
, "Error receiving response to Trans SetUserInfo request\n");
345 SMBlib_errno
= SMBlibE_RecvFailed
;
350 /* Check out the response type ... */
352 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
355 fprintf(stderr
, "SMB_trans SetUserInfo failed with errorclass = %i, Error Code = %i\n",
356 CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
),
357 SVAL(SMB_Hdr(pkt
), SMB_hdr_err_offset
));
360 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
362 SMBlib_errno
= SMBlibE_Remote
;
367 /* All ok, pass back the status */
369 *apiStatus
= SVAL(SMB_Hdr(pkt
), SVAL(SMB_Hdr(pkt
), SMB_transr_pbo_offset
));
376 /* List all the shares available on a server */
378 int SMBapi_NetShareEnum(SMB_Tree_Handle tree
, char *enum_buf
, int bufsiz
,
379 int *shares_returned
, int *shares_total
)