home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- Copyright (c) 1995, 1996 Microsoft Corporation
-
- Module Name:
-
- netshare.c
-
- Abstract:
-
- This module illustrates how to use the Windows NT Lan Manager API
- in conjunction with the Win32 security API to create a new share
- on an arbitrary machine with permissions that grant an arbitrary
- user/group Full Access to the share.
-
- Author:
-
- Scott Field (sfield) 01-Oct-95
-
- --*/
-
- #include <windows.h>
- #include <lm.h>
- #include <stdio.h>
-
- #define RTN_OK 0
- #define RTN_USAGE 1
- #define RTN_ERROR 13
-
- //
- // Note: UNICODE entry point and argv. This way, we don't need to bother
- // with converting commandline args to Unicode
- //
-
- int
- __cdecl
- wmain(
- int argc,
- wchar_t *argv[]
- )
- {
- LPWSTR DirectoryToShare;
- LPWSTR Sharename;
- LPWSTR Username;
- LPWSTR Server;
-
- PSID pSid = NULL;
- DWORD cbSid;
-
- WCHAR RefDomain[DNLEN + 1];
- DWORD cchDomain = DNLEN + 1;
- SID_NAME_USE peUse;
-
- SECURITY_DESCRIPTOR sd;
- PACL pDacl = NULL;
- DWORD dwAclSize;
-
- SHARE_INFO_502 si502;
- NET_API_STATUS nas;
-
- BOOL bSuccess = FALSE; // assume this function fails
-
- if(argc < 4) {
- printf("Usage: %ls <directory> <sharename> <user/group> [\\\\Server]\n", argv[0]);
- printf(" directory is fullpath of directory to share\n");
- printf(" sharename is name of share on server\n");
- printf(" user/group is an WinNT user/groupname (REDMOND\\sfield, Administrators, etc)\n");
- printf(" optional Server is the name of the computer to create the share on\n");
- printf("\nExample: %ls c:\\public public Everyone\n", argv[0]);
- printf("c:\\public shared as public granting Everyone full access\n");
- printf("\nExample: %ls c:\\private cool$ REDMOND\\sfield \\\\WINBASE\n", argv[0]);
- printf("c:\\private on \\\\WINBASE shared as cool$ (hidden) granting REDMOND\\sfield access\n");
-
- return RTN_USAGE;
- }
-
- //
- // since the commandline was Unicode, just provide pointers to
- // the relevant items
- //
-
- DirectoryToShare = argv[1];
- Sharename = argv[2];
- Username = argv[3];
-
- if( argc > 4 ) {
- Server = argv[4];
- } else {
- Server = NULL; // local machine
- }
-
- //
- // initial allocation attempt for Sid
- //
- #define SID_SIZE 96
- cbSid = SID_SIZE;
-
- pSid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);
- if(pSid == NULL) {
- printf("HeapAlloc error!\n");
- return RTN_ERROR;
- }
-
- //
- // get the Sid associated with the supplied user/group name
- // force Unicode API since we always pass Unicode string
- //
-
- if(!LookupAccountNameW(
- NULL, // default lookup logic
- Username, // user/group of interest from commandline
- pSid, // Sid buffer
- &cbSid, // size of Sid
- RefDomain, // Domain account found on (unused)
- &cchDomain, // size of domain in chars
- &peUse
- )) {
-
- //
- // if the buffer wasn't large enough, try again
- //
-
- if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-
- pSid = (PSID)HeapReAlloc(GetProcessHeap(), 0, pSid, cbSid);
-
- if(pSid == NULL) {
- printf("HeapReAlloc error!\n");
- goto cleanup;
- }
-
- cchDomain = DNLEN + 1;
-
- if(!LookupAccountNameW(
- NULL, // default lookup logic
- Username, // user/group of interest from commandline
- pSid, // Sid buffer
- &cbSid, // size of Sid
- RefDomain, // Domain account found on (unused)
- &cchDomain, // size of domain in chars
- &peUse
- )) {
- printf("LookupAccountName error! (rc=%lu)\n", GetLastError());
- goto cleanup;
- }
-
- } else {
- printf("LookupAccountName error! (rc=%lu)\n", GetLastError());
- goto cleanup;
- }
- }
-
- //
- // compute size of new acl
- //
-
- dwAclSize = sizeof(ACL) +
- 1 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
- GetLengthSid(pSid) ;
-
- //
- // allocate storage for Acl
- //
-
- pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
- if(pDacl == NULL) goto cleanup;
-
- if(!InitializeAcl(pDacl, dwAclSize, ACL_REVISION))
- goto cleanup;
-
- //
- // grant GENERIC_ALL (Full Control) access
- //
-
- if(!AddAccessAllowedAce(
- pDacl,
- ACL_REVISION,
- GENERIC_ALL,
- pSid
- )) goto cleanup;
-
- if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
- goto cleanup;
-
- if(!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) {
- fprintf(stderr, "SetSecurityDescriptorDacl error! (rc=%lu)\n",
- GetLastError());
- goto cleanup;
- }
-
- //
- // setup share info structure
- //
-
- si502.shi502_netname = (LPTSTR) Sharename;
- si502.shi502_type = STYPE_DISKTREE;
- si502.shi502_remark = NULL;
- si502.shi502_permissions = 0;
- si502.shi502_max_uses = SHI_USES_UNLIMITED;
- si502.shi502_current_uses = 0;
- si502.shi502_path = (LPTSTR) DirectoryToShare;
- si502.shi502_passwd = NULL;
- si502.shi502_reserved = 0;
- si502.shi502_security_descriptor = &sd;
-
- nas = NetShareAdd(
- (LPTSTR) Server, // share is on local machine
- 502, // info-level
- (LPBYTE)&si502, // info-buffer
- NULL // don't bother with parm
- );
-
- if(nas != NO_ERROR) {
- printf("NetShareAdd error! (rc=%lu)\n", nas);
- goto cleanup;
- }
-
- bSuccess = TRUE; // indicate success
-
- cleanup:
-
- //
- // free allocated resources
- //
- if(pDacl != NULL)
- HeapFree(GetProcessHeap(), 0, pDacl);
-
- if(pSid != NULL)
- HeapFree(GetProcessHeap(), 0, pSid);
-
- if(!bSuccess) {
- return RTN_ERROR;
- }
-
- return RTN_OK;
- }
-
-