2 * Unix library for libnetapi functions
4 * Copyright 2013 Hans Leidekker for CodeWeavers
5 * Copyright 2021 Zebediah Figura for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #ifdef SONAME_LIBNETAPI
34 #include <sys/types.h>
40 #define WIN32_NO_STATUS
44 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(netapi32
);
49 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
51 static void *libnetapi_handle
;
52 static void *libnetapi_ctx
;
54 static DWORD (*plibnetapi_init
)( void ** );
55 static DWORD (*plibnetapi_free
)( void * );
56 static DWORD (*plibnetapi_set_debuglevel
)( void *, const char * );
57 static DWORD (*plibnetapi_set_username
)( void *, const char * );
58 static DWORD (*plibnetapi_set_password
)( void *, const char * );
60 static NET_API_STATUS (*pNetApiBufferAllocate
)( unsigned int, void ** );
61 static NET_API_STATUS (*pNetApiBufferFree
)( void * );
62 static NET_API_STATUS (*pNetServerGetInfo
)( const char *, unsigned int, unsigned char ** );
63 static NET_API_STATUS (*pNetShareAdd
)( const char *, unsigned int, unsigned char *, unsigned int * );
64 static NET_API_STATUS (*pNetShareDel
)( const char *, const char *, unsigned int );
65 static NET_API_STATUS (*pNetWkstaGetInfo
)( const char *, unsigned int, unsigned char ** );
67 static DWORD
netapi_wcstoumbs( const WCHAR
*src
, char *dst
, DWORD dstlen
)
69 if (!dst
) return 3 * wcslen( src
) + 1;
70 return ntdll_wcstoumbs( src
, wcslen( src
) + 1, dst
, dstlen
, FALSE
);
73 static DWORD
netapi_umbstowcs( const char *src
, WCHAR
*dst
, DWORD dstlen
)
75 if (!dst
) return strlen( src
) + 1;
76 return ntdll_umbstowcs( src
, strlen( src
) + 1, dst
, dstlen
);
79 static char *strdup_unixcp( const WCHAR
*str
)
83 int len
= netapi_wcstoumbs( str
, NULL
, 0 );
84 if ((ret
= malloc( len
)))
85 netapi_wcstoumbs( str
, ret
, len
);
89 struct server_info_101
91 unsigned int sv101_platform_id
;
92 const char *sv101_name
;
93 unsigned int sv101_version_major
;
94 unsigned int sv101_version_minor
;
95 unsigned int sv101_type
;
96 const char *sv101_comment
;
99 static NET_API_STATUS
server_info_101_from_samba( const unsigned char *buf
, void *buffer
, ULONG
*size
)
101 SERVER_INFO_101
*ret
= (SERVER_INFO_101
*)buffer
;
102 const struct server_info_101
*info
= (const struct server_info_101
*)buf
;
106 if (info
->sv101_name
) len
+= netapi_umbstowcs( info
->sv101_name
, NULL
, 0 );
107 if (info
->sv101_comment
) len
+= netapi_umbstowcs( info
->sv101_comment
, NULL
, 0 );
108 if (*size
< sizeof(*ret
) + (len
* sizeof(WCHAR
) ))
110 *size
= sizeof(*ret
) + (len
* sizeof(WCHAR
) );
111 return ERROR_INSUFFICIENT_BUFFER
;
114 ptr
= (WCHAR
*)(ret
+ 1);
115 ret
->sv101_platform_id
= info
->sv101_platform_id
;
116 if (!info
->sv101_name
) ret
->sv101_name
= NULL
;
119 ret
->sv101_name
= ptr
;
120 ptr
+= netapi_umbstowcs( info
->sv101_name
, ptr
, len
);
122 ret
->sv101_version_major
= info
->sv101_version_major
;
123 ret
->sv101_version_minor
= info
->sv101_version_minor
;
124 ret
->sv101_type
= info
->sv101_type
;
125 if (!info
->sv101_comment
) ret
->sv101_comment
= NULL
;
128 ret
->sv101_comment
= ptr
;
129 ptr
+= netapi_umbstowcs( info
->sv101_comment
, ptr
, len
);
131 *size
= (char *)ptr
- (char *)buffer
;
135 static NET_API_STATUS
server_info_from_samba( unsigned int level
, const unsigned char *buf
, void *buffer
, ULONG
*size
)
139 case 101: return server_info_101_from_samba( buf
, buffer
, size
);
141 FIXME( "level %u not supported\n", level
);
142 return ERROR_NOT_SUPPORTED
;
146 static NTSTATUS
server_getinfo( void *args
)
148 const struct server_getinfo_params
*params
= args
;
149 NET_API_STATUS status
;
150 char *samba_server
= NULL
;
151 unsigned char *samba_buffer
= NULL
;
153 if (!libnetapi_ctx
) return ERROR_NOT_SUPPORTED
;
155 if (params
->server
&& !(samba_server
= strdup_unixcp( params
->server
))) return ERROR_OUTOFMEMORY
;
156 status
= pNetServerGetInfo( samba_server
, params
->level
, &samba_buffer
);
157 free( samba_server
);
160 status
= server_info_from_samba( params
->level
, samba_buffer
, params
->buffer
, params
->size
);
161 pNetApiBufferFree( samba_buffer
);
168 const char *shi2_netname
;
169 unsigned int shi2_type
;
170 const char *shi2_remark
;
171 unsigned int shi2_permissions
;
172 unsigned int shi2_max_uses
;
173 unsigned int shi2_current_uses
;
174 const char *shi2_path
;
175 const char *shi2_passwd
;
178 static NET_API_STATUS
share_info_2_to_samba( const BYTE
*buf
, unsigned char **bufptr
)
180 struct share_info_2
*ret
;
181 SHARE_INFO_2
*info
= (SHARE_INFO_2
*)buf
;
185 if (info
->shi2_netname
)
186 len
+= netapi_wcstoumbs( info
->shi2_netname
, NULL
, 0 );
187 if (info
->shi2_remark
)
188 len
+= netapi_wcstoumbs( info
->shi2_remark
, NULL
, 0 );
190 len
+= netapi_wcstoumbs( info
->shi2_path
, NULL
, 0 );
191 if (info
->shi2_passwd
)
192 len
+= netapi_wcstoumbs( info
->shi2_passwd
, NULL
, 0 );
193 if (!(ret
= malloc( sizeof(*ret
) + len
)))
194 return ERROR_OUTOFMEMORY
;
196 ptr
= (char *)(ret
+ 1);
197 if (!info
->shi2_netname
) ret
->shi2_netname
= NULL
;
200 ret
->shi2_netname
= ptr
;
201 ptr
+= netapi_wcstoumbs( info
->shi2_netname
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
203 ret
->shi2_type
= info
->shi2_type
;
204 if (!info
->shi2_remark
) ret
->shi2_remark
= NULL
;
207 ret
->shi2_remark
= ptr
;
208 ptr
+= netapi_wcstoumbs( info
->shi2_remark
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
210 ret
->shi2_permissions
= info
->shi2_permissions
;
211 ret
->shi2_max_uses
= info
->shi2_max_uses
;
212 ret
->shi2_current_uses
= info
->shi2_current_uses
;
213 if (!info
->shi2_path
) ret
->shi2_path
= NULL
;
216 ret
->shi2_path
= ptr
;
217 ptr
+= netapi_wcstoumbs( info
->shi2_path
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
219 if (!info
->shi2_passwd
) ret
->shi2_passwd
= NULL
;
222 ret
->shi2_passwd
= ptr
;
223 netapi_wcstoumbs( info
->shi2_passwd
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
225 *bufptr
= (unsigned char *)ret
;
231 unsigned char sid_rev_num
;
232 unsigned char num_auths
;
233 unsigned char id_auth
[6];
234 unsigned int sub_auths
[15];
239 ACE_TYPE_ACCESS_ALLOWED
,
240 ACE_TYPE_ACCESS_DENIED
,
241 ACE_TYPE_SYSTEM_AUDIT
,
242 ACE_TYPE_SYSTEM_ALARM
,
243 ACE_TYPE_ALLOWED_COMPOUND
,
244 ACE_TYPE_ACCESS_ALLOWED_OBJECT
,
245 ACE_TYPE_ACCESS_DENIED_OBJECT
,
246 ACE_TYPE_SYSTEM_AUDIT_OBJECT
,
247 ACE_TYPE_SYSTEM_ALARM_OBJECT
250 #define SEC_ACE_FLAG_OBJECT_INHERIT 0x01
251 #define SEC_ACE_FLAG_CONTAINER_INHERIT 0x02
252 #define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x04
253 #define SEC_ACE_FLAG_INHERIT_ONLY 0x08
254 #define SEC_ACE_FLAG_INHERITED_ACE 0x10
255 #define SEC_ACE_FLAG_SUCCESSFUL_ACCESS 0x40
256 #define SEC_ACE_FLAG_FAILED_ACCESS 0x80
260 unsigned int time_low
;
261 unsigned short time_mid
;
262 unsigned short time_hi_and_version
;
263 unsigned char clock_seq
[2];
264 unsigned char node
[6];
267 union ace_object_type
272 union ace_object_inherited_type
274 struct guid inherited_type
;
280 union ace_object_type type
;
281 union ace_object_inherited_type inherited_type
;
286 struct ace_object object
;
294 unsigned int access_mask
;
295 union ace_object_ctr object
;
301 ACL_REVISION_NT4
= 2,
307 enum acl_revision revision
;
309 unsigned int num_aces
;
313 enum security_descriptor_revision
315 SECURITY_DESCRIPTOR_REVISION_1
= 1
318 #define SEC_DESC_OWNER_DEFAULTED 0x0001
319 #define SEC_DESC_GROUP_DEFAULTED 0x0002
320 #define SEC_DESC_DACL_PRESENT 0x0004
321 #define SEC_DESC_DACL_DEFAULTED 0x0008
322 #define SEC_DESC_SACL_PRESENT 0x0010
323 #define SEC_DESC_SACL_DEFAULTED 0x0020
324 #define SEC_DESC_DACL_TRUSTED 0x0040
325 #define SEC_DESC_SERVER_SECURITY 0x0080
326 #define SEC_DESC_DACL_AUTO_INHERIT_REQ 0x0100
327 #define SEC_DESC_SACL_AUTO_INHERIT_REQ 0x0200
328 #define SEC_DESC_DACL_AUTO_INHERITED 0x0400
329 #define SEC_DESC_SACL_AUTO_INHERITED 0x0800
330 #define SEC_DESC_DACL_PROTECTED 0x1000
331 #define SEC_DESC_SACL_PROTECTED 0x2000
332 #define SEC_DESC_RM_CONTROL_VALID 0x4000
333 #define SEC_DESC_SELF_RELATIVE 0x8000
335 struct security_descriptor
337 enum security_descriptor_revision revision
;
339 struct sid
*owner_sid
;
340 struct sid
*group_sid
;
345 struct share_info_502
347 const char *shi502_netname
;
348 unsigned int shi502_type
;
349 const char *shi502_remark
;
350 unsigned int shi502_permissions
;
351 unsigned int shi502_max_uses
;
352 unsigned int shi502_current_uses
;
353 const char *shi502_path
;
354 const char *shi502_passwd
;
355 unsigned int shi502_reserved
;
356 struct security_descriptor
*shi502_security_descriptor
;
359 static unsigned short sd_control_to_samba( SECURITY_DESCRIPTOR_CONTROL control
)
361 unsigned short ret
= 0;
363 if (control
& SE_OWNER_DEFAULTED
) ret
|= SEC_DESC_OWNER_DEFAULTED
;
364 if (control
& SE_GROUP_DEFAULTED
) ret
|= SEC_DESC_GROUP_DEFAULTED
;
365 if (control
& SE_DACL_PRESENT
) ret
|= SEC_DESC_DACL_PRESENT
;
366 if (control
& SE_DACL_DEFAULTED
) ret
|= SEC_DESC_DACL_DEFAULTED
;
367 if (control
& SE_SACL_PRESENT
) ret
|= SEC_DESC_SACL_PRESENT
;
368 if (control
& SE_SACL_DEFAULTED
) ret
|= SEC_DESC_SACL_DEFAULTED
;
369 if (control
& SE_DACL_AUTO_INHERIT_REQ
) ret
|= SEC_DESC_DACL_AUTO_INHERIT_REQ
;
370 if (control
& SE_SACL_AUTO_INHERIT_REQ
) ret
|= SEC_DESC_SACL_AUTO_INHERIT_REQ
;
371 if (control
& SE_DACL_AUTO_INHERITED
) ret
|= SEC_DESC_DACL_AUTO_INHERITED
;
372 if (control
& SE_SACL_AUTO_INHERITED
) ret
|= SEC_DESC_SACL_AUTO_INHERITED
;
373 if (control
& SE_DACL_PROTECTED
) ret
|= SEC_DESC_DACL_PROTECTED
;
374 if (control
& SE_SACL_PROTECTED
) ret
|= SEC_DESC_SACL_PROTECTED
;
375 if (control
& SE_RM_CONTROL_VALID
) ret
|= SEC_DESC_RM_CONTROL_VALID
;
379 static NET_API_STATUS
sid_to_samba( const SID
*src
, struct sid
*dst
)
383 if (src
->Revision
!= 1)
385 ERR( "unknown revision %u\n", src
->Revision
);
386 return ERROR_UNKNOWN_REVISION
;
388 if (src
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
390 WARN( "invalid subauthority count %u\n", src
->SubAuthorityCount
);
391 return ERROR_INVALID_PARAMETER
;
393 dst
->sid_rev_num
= SECURITY_DESCRIPTOR_REVISION_1
;
394 dst
->num_auths
= src
->SubAuthorityCount
;
395 for (i
= 0; i
< 6; i
++) dst
->id_auth
[i
] = src
->IdentifierAuthority
.Value
[i
];
396 for (i
= 0; i
< dst
->num_auths
; i
++) dst
->sub_auths
[i
] = src
->SubAuthority
[i
];
400 static enum ace_type
ace_type_to_samba( BYTE type
)
404 case ACCESS_ALLOWED_ACE_TYPE
: return ACE_TYPE_ACCESS_ALLOWED
;
405 case ACCESS_DENIED_ACE_TYPE
: return ACE_TYPE_ACCESS_DENIED
;
406 case SYSTEM_AUDIT_ACE_TYPE
: return ACE_TYPE_SYSTEM_AUDIT
;
407 case SYSTEM_ALARM_ACE_TYPE
: return ACE_TYPE_SYSTEM_ALARM
;
409 ERR( "unhandled type %u\n", type
);
414 static unsigned char ace_flags_to_samba( BYTE flags
)
416 static const BYTE known_flags
=
417 OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
| NO_PROPAGATE_INHERIT_ACE
|
418 INHERIT_ONLY_ACE
| INHERITED_ACE
| SUCCESSFUL_ACCESS_ACE_FLAG
| FAILED_ACCESS_ACE_FLAG
;
419 unsigned char ret
= 0;
421 if (flags
& ~known_flags
)
423 ERR( "unknown flags %x\n", flags
& ~known_flags
);
426 if (flags
& OBJECT_INHERIT_ACE
) ret
|= SEC_ACE_FLAG_OBJECT_INHERIT
;
427 if (flags
& CONTAINER_INHERIT_ACE
) ret
|= SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
;
428 if (flags
& NO_PROPAGATE_INHERIT_ACE
) ret
|= SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
;
429 if (flags
& INHERIT_ONLY_ACE
) ret
|= SEC_ACE_FLAG_INHERIT_ONLY
;
430 if (flags
& INHERITED_ACE
) ret
|= SEC_ACE_FLAG_INHERITED_ACE
;
431 if (flags
& SUCCESSFUL_ACCESS_ACE_FLAG
) ret
|= SEC_ACE_FLAG_SUCCESSFUL_ACCESS
;
432 if (flags
& FAILED_ACCESS_ACE_FLAG
) ret
|= SEC_ACE_FLAG_FAILED_ACCESS
;
436 #define GENERIC_ALL_ACCESS (1u << 28)
437 #define GENERIC_EXECUTE_ACCESS (1u << 29)
438 #define GENERIC_WRITE_ACCESS (1u << 30)
439 #define GENERIC_READ_ACCESS (1u << 31)
441 static unsigned int access_mask_to_samba( unsigned int mask
)
443 static const unsigned int known_rights
=
444 GENERIC_ALL
| GENERIC_EXECUTE
| GENERIC_WRITE
| GENERIC_READ
;
445 unsigned int ret
= 0;
447 if (mask
& ~known_rights
)
449 ERR( "unknown rights %x\n", mask
& ~known_rights
);
452 if (mask
& GENERIC_ALL
) ret
|= GENERIC_ALL_ACCESS
;
453 if (mask
& GENERIC_EXECUTE
) ret
|= GENERIC_EXECUTE_ACCESS
;
454 if (mask
& GENERIC_WRITE
) ret
|= GENERIC_WRITE_ACCESS
;
455 if (mask
& GENERIC_READ
) ret
|= GENERIC_READ_ACCESS
;
459 static NET_API_STATUS
ace_to_samba( const ACE_HEADER
*src
, struct ace
*dst
)
461 dst
->type
= ace_type_to_samba( src
->AceType
);
462 dst
->flags
= ace_flags_to_samba( src
->AceFlags
);
463 dst
->size
= sizeof(*dst
);
464 switch (src
->AceType
)
466 case ACCESS_ALLOWED_ACE_TYPE
:
468 ACCESS_ALLOWED_ACE
*ace
= (ACCESS_ALLOWED_ACE
*)src
;
469 dst
->access_mask
= access_mask_to_samba( ace
->Mask
);
470 memset( &dst
->object
, 0, sizeof(dst
->object
) );
471 sid_to_samba( (const SID
*)&ace
->SidStart
, &dst
->trustee
);
474 case ACCESS_DENIED_ACE_TYPE
:
476 ACCESS_DENIED_ACE
*ace
= (ACCESS_DENIED_ACE
*)src
;
477 dst
->access_mask
= access_mask_to_samba( ace
->Mask
);
478 memset( &dst
->object
, 0, sizeof(dst
->object
) );
479 sid_to_samba( (const SID
*)&ace
->SidStart
, &dst
->trustee
);
482 case SYSTEM_AUDIT_ACE_TYPE
:
484 SYSTEM_AUDIT_ACE
*ace
= (SYSTEM_AUDIT_ACE
*)src
;
485 dst
->access_mask
= access_mask_to_samba( ace
->Mask
);
486 memset( &dst
->object
, 0, sizeof(dst
->object
) );
487 sid_to_samba( (const SID
*)&ace
->SidStart
, &dst
->trustee
);
490 case SYSTEM_ALARM_ACE_TYPE
:
492 SYSTEM_ALARM_ACE
*ace
= (SYSTEM_ALARM_ACE
*)src
;
493 dst
->access_mask
= access_mask_to_samba( ace
->Mask
);
494 memset( &dst
->object
, 0, sizeof(dst
->object
) );
495 sid_to_samba( (const SID
*)&ace
->SidStart
, &dst
->trustee
);
499 ERR( "unhandled type %u\n", src
->AceType
);
500 return ERROR_INVALID_PARAMETER
;
505 static NET_API_STATUS
acl_to_samba( const ACL
*src
, struct acl
*dst
)
507 NET_API_STATUS status
;
511 switch (src
->AclRevision
)
514 dst
->revision
= ACL_REVISION_ADS
;
517 ERR( "unkhandled revision %u\n", src
->AclRevision
);
518 return ERROR_UNKNOWN_REVISION
;
520 dst
->size
= sizeof(*dst
);
521 src_ace
= (ACE_HEADER
*)(src
+ 1);
522 dst
->aces
= (struct ace
*)(dst
+ 1);
523 for (i
= 0; i
< src
->AceCount
; i
++)
525 if ((status
= ace_to_samba( src_ace
, &dst
->aces
[i
] ))) return status
;
526 src_ace
= (ACE_HEADER
*)((char *)src_ace
+ src_ace
->AceSize
);
527 dst
->size
+= dst
->aces
[i
].size
;
532 #define SELF_RELATIVE_FIELD(sd,field)\
533 ((char *)(sd) + ((SECURITY_DESCRIPTOR_RELATIVE *)(sd))->field)
535 static NET_API_STATUS
sd_to_samba( const SECURITY_DESCRIPTOR
*src
, struct security_descriptor
*dst
)
537 NET_API_STATUS status
;
538 const SID
*owner
, *group
;
539 const ACL
*dacl
, *sacl
;
540 unsigned int offset
= sizeof(*dst
);
542 if (src
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
543 return ERROR_UNKNOWN_REVISION
;
545 dst
->revision
= SECURITY_DESCRIPTOR_REVISION_1
;
546 dst
->type
= sd_control_to_samba( src
->Control
);
548 if (src
->Control
& SE_SELF_RELATIVE
)
550 if (!src
->Owner
) dst
->owner_sid
= NULL
;
553 dst
->owner_sid
= (struct sid
*)((char *)dst
+ offset
);
554 owner
= (const SID
*)SELF_RELATIVE_FIELD( src
, Owner
);
555 if ((status
= sid_to_samba( owner
, dst
->owner_sid
))) return status
;
556 offset
+= sizeof(struct sid
);
558 if (!src
->Group
) dst
->group_sid
= NULL
;
561 dst
->group_sid
= (struct sid
*)((char *)dst
+ offset
);
562 group
= (const SID
*)SELF_RELATIVE_FIELD( src
, Group
);
563 if ((status
= sid_to_samba( group
, dst
->group_sid
))) return status
;
564 offset
+= sizeof(struct sid
);
566 if (!(src
->Control
& SE_SACL_PRESENT
)) dst
->sacl
= NULL
;
569 dst
->sacl
= (struct acl
*)((char *)dst
+ offset
);
570 sacl
= (const ACL
*)SELF_RELATIVE_FIELD( src
, Sacl
);
571 if ((status
= acl_to_samba( sacl
, dst
->sacl
))) return status
;
572 offset
+= dst
->sacl
->size
;
574 if (!(src
->Control
& SE_DACL_PRESENT
)) dst
->dacl
= NULL
;
577 dst
->dacl
= (struct acl
*)((char *)dst
+ offset
);
578 dacl
= (const ACL
*)SELF_RELATIVE_FIELD( src
, Dacl
);
579 if ((status
= acl_to_samba( dacl
, dst
->dacl
))) return status
;
584 if (!src
->Owner
) dst
->owner_sid
= NULL
;
587 dst
->owner_sid
= (struct sid
*)((char *)dst
+ offset
);
588 if ((status
= sid_to_samba( src
->Owner
, dst
->owner_sid
))) return status
;
589 offset
+= sizeof(struct sid
);
591 if (!src
->Group
) dst
->group_sid
= NULL
;
594 dst
->group_sid
= (struct sid
*)((char *)dst
+ offset
);
595 if ((status
= sid_to_samba( src
->Group
, dst
->group_sid
))) return status
;
596 offset
+= sizeof(struct sid
);
598 if (!(src
->Control
& SE_SACL_PRESENT
)) dst
->sacl
= NULL
;
601 dst
->sacl
= (struct acl
*)((char *)dst
+ offset
);
602 if ((status
= acl_to_samba( src
->Sacl
, dst
->sacl
))) return status
;
603 offset
+= dst
->sacl
->size
;
605 if (!(src
->Control
& SE_DACL_PRESENT
)) dst
->dacl
= NULL
;
608 dst
->dacl
= (struct acl
*)((char *)dst
+ offset
);
609 if ((status
= acl_to_samba( src
->Dacl
, dst
->dacl
))) return status
;
615 static unsigned int sd_to_samba_size( const SECURITY_DESCRIPTOR
*sd
)
617 unsigned int ret
= sizeof(struct security_descriptor
);
619 if (sd
->Owner
) ret
+= sizeof(struct sid
);
620 if (sd
->Group
) ret
+= sizeof(struct sid
);
621 if (sd
->Control
& SE_SACL_PRESENT
)
622 ret
+= sizeof(struct acl
) + sd
->Sacl
->AceCount
* sizeof(struct ace
);
623 if (sd
->Control
& SE_DACL_PRESENT
)
624 ret
+= sizeof(struct acl
) + sd
->Dacl
->AceCount
* sizeof(struct ace
);
628 static NET_API_STATUS
share_info_502_to_samba( const BYTE
*buf
, unsigned char **bufptr
)
630 NET_API_STATUS status
;
631 struct share_info_502
*ret
;
632 SHARE_INFO_502
*info
= (SHARE_INFO_502
*)buf
;
633 DWORD len
= 0, size
= 0;
637 if (info
->shi502_netname
)
638 len
+= netapi_wcstoumbs( info
->shi502_netname
, NULL
, 0 );
639 if (info
->shi502_remark
)
640 len
+= netapi_wcstoumbs( info
->shi502_remark
, NULL
, 0 );
641 if (info
->shi502_path
)
642 len
+= netapi_wcstoumbs( info
->shi502_path
, NULL
, 0 );
643 if (info
->shi502_passwd
)
644 len
+= netapi_wcstoumbs( info
->shi502_passwd
, NULL
, 0 );
645 if (info
->shi502_security_descriptor
)
646 size
= sd_to_samba_size( info
->shi502_security_descriptor
);
647 if (!(ret
= malloc( sizeof(*ret
) + (len
* sizeof(WCHAR
)) + size
)))
648 return ERROR_OUTOFMEMORY
;
650 ptr
= (char *)(ret
+ 1);
651 if (!info
->shi502_netname
) ret
->shi502_netname
= NULL
;
654 ret
->shi502_netname
= ptr
;
655 ptr
+= netapi_wcstoumbs( info
->shi502_netname
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
657 ret
->shi502_type
= info
->shi502_type
;
658 if (!info
->shi502_remark
) ret
->shi502_remark
= NULL
;
661 ret
->shi502_remark
= ptr
;
662 ptr
+= netapi_wcstoumbs( info
->shi502_remark
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
664 ret
->shi502_permissions
= info
->shi502_permissions
;
665 ret
->shi502_max_uses
= info
->shi502_max_uses
;
666 ret
->shi502_current_uses
= info
->shi502_current_uses
;
667 if (!info
->shi502_path
) ret
->shi502_path
= NULL
;
670 ret
->shi502_path
= ptr
;
671 ptr
+= netapi_wcstoumbs( info
->shi502_path
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
673 if (!info
->shi502_passwd
) ret
->shi502_passwd
= NULL
;
676 ret
->shi502_passwd
= ptr
;
677 ptr
+= netapi_wcstoumbs( info
->shi502_passwd
, ptr
, len
- (ptr
- (char *)(ret
+ 1)) );
679 ret
->shi502_reserved
= info
->shi502_reserved
;
680 if (!info
->shi502_security_descriptor
) ret
->shi502_security_descriptor
= NULL
;
683 status
= sd_to_samba( info
->shi502_security_descriptor
, (struct security_descriptor
*)ptr
);
689 ret
->shi502_security_descriptor
= (struct security_descriptor
*)ptr
;
691 *bufptr
= (unsigned char *)ret
;
695 static NET_API_STATUS
share_info_to_samba( unsigned int level
, const BYTE
*buf
, unsigned char **bufptr
)
699 case 2: return share_info_2_to_samba( buf
, bufptr
);
700 case 502: return share_info_502_to_samba( buf
, bufptr
);
702 FIXME( "level %u not supported\n", level
);
703 return ERROR_NOT_SUPPORTED
;
707 static NTSTATUS
share_add( void *args
)
709 const struct share_add_params
*params
= args
;
710 char *samba_server
= NULL
;
711 unsigned char *samba_info
;
712 NET_API_STATUS status
;
714 if (!libnetapi_ctx
) return ERROR_NOT_SUPPORTED
;
716 if (params
->server
&& !(samba_server
= strdup_unixcp( params
->server
))) return ERROR_OUTOFMEMORY
;
717 status
= share_info_to_samba( params
->level
, params
->info
, &samba_info
);
720 unsigned int samba_err
;
722 status
= pNetShareAdd( samba_server
, params
->level
, samba_info
, &samba_err
);
724 if (params
->err
) *params
->err
= samba_err
;
726 free( samba_server
);
730 static NTSTATUS
share_del( void *args
)
732 const struct share_del_params
*params
= args
;
733 char *samba_server
= NULL
, *samba_share
;
734 NET_API_STATUS status
;
736 if (!libnetapi_ctx
) return ERROR_NOT_SUPPORTED
;
738 if (params
->server
&& !(samba_server
= strdup_unixcp( params
->server
))) return ERROR_OUTOFMEMORY
;
739 if (!(samba_share
= strdup_unixcp( params
->share
)))
741 free( samba_server
);
742 return ERROR_OUTOFMEMORY
;
744 status
= pNetShareDel( samba_server
, samba_share
, params
->reserved
);
745 free( samba_server
);
750 struct wksta_info_100
752 unsigned int wki100_platform_id
;
753 const char *wki100_computername
;
754 const char *wki100_langroup
;
755 unsigned int wki100_ver_major
;
756 unsigned int wki100_ver_minor
;
759 static NET_API_STATUS
wksta_info_100_from_samba( const unsigned char *buf
, void *buffer
, ULONG
*size
)
761 WKSTA_INFO_100
*ret
= (WKSTA_INFO_100
*)buffer
;
762 const struct wksta_info_100
*info
= (const struct wksta_info_100
*)buf
;
766 if (info
->wki100_computername
)
767 len
+= netapi_umbstowcs( info
->wki100_computername
, NULL
, 0 );
768 if (info
->wki100_langroup
)
769 len
+= netapi_umbstowcs( info
->wki100_langroup
, NULL
, 0 );
770 if (*size
< sizeof(*ret
) + (len
* sizeof(WCHAR
) ))
772 *size
= sizeof(*ret
) + (len
* sizeof(WCHAR
) );
773 return ERROR_INSUFFICIENT_BUFFER
;
776 ptr
= (WCHAR
*)(ret
+ 1);
777 ret
->wki100_platform_id
= info
->wki100_platform_id
;
778 if (!info
->wki100_computername
) ret
->wki100_computername
= NULL
;
781 ret
->wki100_computername
= ptr
;
782 ptr
+= netapi_umbstowcs( info
->wki100_computername
, ptr
, len
);
784 if (!info
->wki100_langroup
) ret
->wki100_langroup
= NULL
;
787 ret
->wki100_langroup
= ptr
;
788 ptr
+= netapi_umbstowcs( info
->wki100_langroup
, ptr
, len
);
790 ret
->wki100_ver_major
= info
->wki100_ver_major
;
791 ret
->wki100_ver_minor
= info
->wki100_ver_minor
;
792 *size
= (char *)ptr
- (char *)buffer
;
796 static NET_API_STATUS
wksta_info_from_samba( unsigned int level
, const unsigned char *buf
, void *buffer
, ULONG
*size
)
800 case 100: return wksta_info_100_from_samba( buf
, buffer
, size
);
802 FIXME( "level %u not supported\n", level
);
803 return ERROR_NOT_SUPPORTED
;
807 static NTSTATUS
wksta_getinfo( void *args
)
809 const struct wksta_getinfo_params
*params
= args
;
810 unsigned char *samba_buffer
= NULL
;
811 char *samba_server
= NULL
;
812 NET_API_STATUS status
;
814 if (!libnetapi_ctx
) return ERROR_NOT_SUPPORTED
;
816 if (params
->server
&& !(samba_server
= strdup_unixcp( params
->server
))) return ERROR_OUTOFMEMORY
;
817 status
= pNetWkstaGetInfo( samba_server
, params
->level
, &samba_buffer
);
818 free( samba_server
);
821 status
= wksta_info_from_samba( params
->level
, samba_buffer
, params
->buffer
, params
->size
);
822 pNetApiBufferFree( samba_buffer
);
827 static NTSTATUS
netapi_init( void *args
)
832 if (!(libnetapi_handle
= dlopen( SONAME_LIBNETAPI
, RTLD_NOW
)))
834 ERR_(winediag
)( "failed to load %s\n", SONAME_LIBNETAPI
);
835 return STATUS_DLL_NOT_FOUND
;
838 #define LOAD_FUNCPTR(f) \
839 if (!(p##f = dlsym( libnetapi_handle, #f ))) \
841 ERR_(winediag)( "%s not found in %s\n", #f, SONAME_LIBNETAPI ); \
842 return STATUS_DLL_NOT_FOUND; \
845 LOAD_FUNCPTR(libnetapi_init
)
846 LOAD_FUNCPTR(libnetapi_free
)
847 LOAD_FUNCPTR(libnetapi_set_debuglevel
)
848 LOAD_FUNCPTR(libnetapi_set_username
)
849 LOAD_FUNCPTR(libnetapi_set_password
)
851 LOAD_FUNCPTR(NetApiBufferAllocate
)
852 LOAD_FUNCPTR(NetApiBufferFree
)
853 LOAD_FUNCPTR(NetServerGetInfo
)
854 LOAD_FUNCPTR(NetShareAdd
)
855 LOAD_FUNCPTR(NetShareDel
)
856 LOAD_FUNCPTR(NetWkstaGetInfo
)
859 if ((status
= plibnetapi_init( &ctx
)))
861 ERR( "Failed to initialize context, status %u\n", status
);
862 return STATUS_DLL_NOT_FOUND
;
864 if (TRACE_ON(netapi32
) && (status
= plibnetapi_set_debuglevel( ctx
, "10" )))
866 ERR( "Failed to set debug level, status %u\n", status
);
867 plibnetapi_free( ctx
);
868 return STATUS_DLL_NOT_FOUND
;
870 /* perform an anonymous login by default (avoids a password prompt) */
871 if ((status
= plibnetapi_set_username( ctx
, "Guest" )))
873 ERR( "Failed to set username, status %u\n", status
);
874 plibnetapi_free( ctx
);
875 return STATUS_DLL_NOT_FOUND
;
877 if ((status
= plibnetapi_set_password( ctx
, "" )))
879 ERR( "Failed to set password, status %u\n", status
);
880 plibnetapi_free( ctx
);
881 return STATUS_DLL_NOT_FOUND
;
885 return STATUS_SUCCESS
;
888 static NTSTATUS
change_password( void *args
)
890 const struct change_password_params
*params
= args
;
891 NET_API_STATUS ret
= NERR_Success
;
892 static char option_silent
[] = "-s";
893 static char option_user
[] = "-U";
894 static char option_remote
[] = "-r";
895 static char smbpasswd
[] = "smbpasswd";
899 char *server
= NULL
, *user
, *argv
[7], *old
= NULL
, *new = NULL
;
901 if (params
->domain
&& !(server
= strdup_unixcp( params
->domain
))) return ERROR_OUTOFMEMORY
;
902 if (!(user
= strdup_unixcp( params
->user
)))
904 ret
= ERROR_OUTOFMEMORY
;
907 if (!(old
= strdup_unixcp( params
->old
)))
909 ret
= ERROR_OUTOFMEMORY
;
912 if (!(new = strdup_unixcp( params
->new )))
914 ret
= ERROR_OUTOFMEMORY
;
918 argv
[1] = option_silent
;
919 argv
[2] = option_user
;
923 argv
[4] = option_remote
;
929 if (pipe( pipe_out
) == -1)
931 ret
= NERR_InternalError
;
934 fcntl( pipe_out
[0], F_SETFD
, FD_CLOEXEC
);
935 fcntl( pipe_out
[1], F_SETFD
, FD_CLOEXEC
);
937 switch ((pid
= fork()))
940 close( pipe_out
[0] );
941 close( pipe_out
[1] );
942 ret
= NERR_InternalError
;
945 dup2( pipe_out
[0], 0 );
946 close( pipe_out
[0] );
947 close( pipe_out
[1] );
948 execvp( "smbpasswd", argv
);
949 ERR( "can't execute smbpasswd, is it installed?\n" );
952 close( pipe_out
[0] );
955 write( pipe_out
[1], old
, strlen( old
) );
956 write( pipe_out
[1], "\n", 1 );
957 write( pipe_out
[1], new, strlen( new ) );
958 write( pipe_out
[1], "\n", 1 );
959 write( pipe_out
[1], new, strlen( new ) );
960 write( pipe_out
[1], "\n", 1 );
961 close( pipe_out
[1] );
964 wret
= waitpid(pid
, &status
, 0);
965 } while (wret
< 0 && errno
== EINTR
);
967 if (ret
== NERR_Success
&& (wret
< 0 || !WIFEXITED(status
) || WEXITSTATUS(status
)))
968 ret
= NERR_InternalError
;
978 const unixlib_entry_t __wine_unix_call_funcs
[] =
988 C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs
) == unix_funcs_count
);
994 static NTSTATUS
wow64_server_getinfo( void *args
)
1002 } const *params32
= args
;
1004 struct server_getinfo_params params
=
1006 ULongToPtr(params32
->server
),
1008 ULongToPtr(params32
->buffer
),
1009 ULongToPtr(params32
->size
)
1012 return server_getinfo( ¶ms
);
1015 static NTSTATUS
wow64_share_add( void *args
)
1023 } const *params32
= args
;
1025 struct share_add_params params
=
1027 ULongToPtr(params32
->server
),
1029 ULongToPtr(params32
->info
),
1030 ULongToPtr(params32
->err
)
1033 return share_add( ¶ms
);
1036 static NTSTATUS
wow64_share_del( void *args
)
1043 } const *params32
= args
;
1045 struct share_del_params params
=
1047 ULongToPtr(params32
->server
),
1048 ULongToPtr(params32
->share
),
1052 return share_del( ¶ms
);
1055 static NTSTATUS
wow64_wksta_getinfo( void *args
)
1063 } const *params32
= args
;
1065 struct wksta_getinfo_params params
=
1067 ULongToPtr(params32
->server
),
1069 ULongToPtr(params32
->buffer
),
1070 ULongToPtr(params32
->size
)
1073 return wksta_getinfo( ¶ms
);
1076 static NTSTATUS
wow64_change_password( void *args
)
1084 } const *params32
= args
;
1086 struct change_password_params params
=
1088 ULongToPtr(params32
->domain
),
1089 ULongToPtr(params32
->user
),
1090 ULongToPtr(params32
->old
),
1091 ULongToPtr(params32
->new)
1094 return change_password( ¶ms
);
1097 const unixlib_entry_t __wine_unix_call_wow64_funcs
[] =
1100 wow64_server_getinfo
,
1103 wow64_wksta_getinfo
,
1104 wow64_change_password
,
1107 C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs
) == unix_funcs_count
);
1111 #endif /* SONAME_LIBNETAPI */