static long GetDomainJoinState(PSTR* ppszDomain) { long macError = eDSNoErr; PSTR pszDomain = NULL; macError = GetCurrentDomain(&pszDomain); if (macError) { // ISSUE-2008/10/07-dalmeida -- Assume not joined? macError = eDSNoErr; } GOTO_CLEANUP_ON_MACERROR(macError); if (pszDomain) { LwStrToUpper(pszDomain); } cleanup: if (macError) { LW_SAFE_FREE_STRING(pszDomain); pszDomain = NULL; } *ppszDomain = pszDomain; return macError; }
static DWORD SetMachineName( PSTR pszName ) { DWORD dwError = 0; HANDLE hLsaConnection = NULL; BAIL_ON_INVALID_STRING(pszName); dwError = LsaOpenServer(&hLsaConnection); BAIL_ON_LSA_ERROR(dwError); LwStrToUpper(pszName); dwError = LsaSetMachineName(hLsaConnection, pszName); BAIL_ON_LSA_ERROR(dwError); fprintf(stdout, "Successfully set machine name to %s\n", pszName); cleanup: if (hLsaConnection != (HANDLE)NULL) { LsaCloseServer(hLsaConnection); } return dwError; error: goto cleanup; }
static DWORD CleanupUsername( IN PCSTR pszDomain, IN OUT PSTR* ppszUsername ) { DWORD dwError = 0; PSTR pszOldUsername = *ppszUsername; PSTR pszNewUsername = NULL; // Fix up username and prompt for password, if needed. if (pszOldUsername) { PSTR at = NULL; if (strchr(pszOldUsername, '\\')) { fprintf(stderr, "The USERNAME (%s) is not allowed to contain a backslash.\n", pszOldUsername); exit(1); } at = strchr(pszOldUsername, '@'); if (at) { LwStrToUpper(at); } else { dwError = LwAllocateStringPrintf( &pszNewUsername, "%s@%s", pszOldUsername, pszDomain); GOTO_CLEANUP_ON_WINERROR(dwError); } } cleanup: if (dwError) { LW_SAFE_FREE_MEMORY(pszNewUsername); } if (pszNewUsername) { LW_SAFE_FREE_MEMORY(*ppszUsername); *ppszUsername = pszNewUsername; } return dwError; }
VOID LsaPrincipalRealmToUpper( IN OUT PSTR pszPrincipal ) { PSTR pszAt = NULL; pszAt = strchr(pszPrincipal, '@'); if (pszAt) { LwStrToUpper(pszAt + 1); } }
DWORD AD_GetUserDomainPrefix( PLSA_AD_PROVIDER_STATE pState, PSTR* ppszPath ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; PSTR pszValue = NULL; ENTER_AD_CONFIG_RW_READER_LOCK(bInLock, pState); if (!LW_IS_NULL_OR_EMPTY_STR(pState->config.pszUserDomainPrefix)) { dwError = LwAllocateString( pState->config.pszUserDomainPrefix, &pszValue ); BAIL_ON_LSA_ERROR(dwError); } else if (pState->pProviderData && !LW_IS_NULL_OR_EMPTY_STR(pState->pProviderData->szShortDomain)) { dwError = LwAllocateString( pState->pProviderData->szShortDomain, &pszValue ); BAIL_ON_LSA_ERROR(dwError); } LwStrToUpper(pszValue); *ppszPath = pszValue; cleanup: LEAVE_AD_CONFIG_RW_READER_LOCK(bInLock, pState); return dwError; error: *ppszPath = NULL; goto cleanup; }
static DWORD ParseLeaveArgs( IN int argc, IN const char *argv[], OUT PLEAVE_ARGS pArgs ) { DWORD dwError = 0; PCSTR programName = NULL; PCSTR option = NULL; LW_ARGV_CURSOR cursor; SHOW_USAGE_CALLBACK ShowUsageHelp = ShowLeaveUsageHelp; SHOW_USAGE_CALLBACK ShowUsageError = ShowLeaveUsageError; memset(pArgs, 0, sizeof(*pArgs)); LwArgvCursorInit(&cursor, argc, argv); programName = LwArgvCursorPop(&cursor); // Process options: for (;;) { option = PopNextOption(&cursor); if (!option) { break; } else if (IsHelpOption(option)) { ShowUsageHelp(programName); } else if (!strcmp("--multiple", option)) { SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE); dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszDomain); GOTO_CLEANUP_ON_WINERROR(dwError); LwStrToUpper(pArgs->pszDomain); } else { fprintf(stderr, "Unrecognized option: %s\n", option); ShowUsageError(programName); } } // Optional arguments dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL, &pArgs->pszUsername); assert(!dwError); dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL, &pArgs->pszPassword); assert(!dwError); if (LwArgvCursorRemaining(&cursor)) { fprintf(stderr, "Too many arguments.\n"); ShowUsageError(programName); } // Initialize implicit domain argument. if (!pArgs->pszDomain) { dwError = GetCurrentDomain(&pArgs->pszDomain); if (NERR_SetupNotJoined == dwError) { fprintf(stderr, "The computer is not joined to a domain.\n"); exit(1); } GOTO_CLEANUP_ON_WINERROR(dwError); } // If USERNAME was specified, clean it up and get password // as needed. if (pArgs->pszUsername) { dwError = CleanupUsername(pArgs->pszDomain, &pArgs->pszUsername); GOTO_CLEANUP_ON_WINERROR(dwError); if (!pArgs->pszPassword) { dwError = PromptPassword(pArgs->pszUsername, &pArgs->pszPassword); GOTO_CLEANUP_ON_WINERROR(dwError); } } cleanup: if (dwError) { FreeLeaveArgsContents(pArgs); } return dwError; }
static DWORD ParseJoinArgs( IN int argc, IN const char *argv[], OUT PJOIN_ARGS pArgs ) { DWORD dwError = 0; PCSTR programName = NULL; PCSTR option = NULL; LW_ARGV_CURSOR cursor; SHOW_USAGE_CALLBACK ShowUsageHelp = ShowJoinUsageHelp; SHOW_USAGE_CALLBACK ShowUsageError = ShowJoinUsageError; memset(pArgs, 0, sizeof(*pArgs)); LwArgvCursorInit(&cursor, argc, argv); programName = LwArgvCursorPop(&cursor); // Process options: for (;;) { option = PopNextOption(&cursor); if (!option) { break; } else if (IsHelpOption(option)) { ShowUsageHelp(programName); } else if (!strcmp("--name", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszMachineName); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--dnssuffix", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszDnsSuffix); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--ou", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOu); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--osname", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOsName); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--osversion", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOsVersion); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--osservicepack", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOsServicePack); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--notimesync", option)) { SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_NOTIMESYNC); } else if (!strcmp("--multiple", option)) { SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_NOTIMESYNC); SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE); } else { fprintf(stderr, "Unrecognized option: %s\n", option); ShowUsageError(programName); } } // Process arguments: dwError = GetArgumentValue(programName, ShowUsageError, &cursor, "DOMAIN", &pArgs->pszDomain); GOTO_CLEANUP_ON_WINERROR(dwError); LwStrToUpper(pArgs->pszDomain); dwError = GetArgumentValue(programName, ShowUsageError, &cursor, "USERNAME", &pArgs->pszUsername); GOTO_CLEANUP_ON_WINERROR(dwError); // Optional argument dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL, &pArgs->pszPassword); assert(!dwError); if (LwArgvCursorRemaining(&cursor)) { fprintf(stderr, "Too many arguments.\n"); ShowUsageError(programName); } // Initialize missing options as needed if (!pArgs->pszDnsSuffix) { dwError = LwAllocateString(pArgs->pszDomain, &pArgs->pszDnsSuffix); GOTO_CLEANUP_ON_WINERROR(dwError); } LwStrToLower(pArgs->pszDnsSuffix); if (!pArgs->pszMachineName) { dwError = GetHostname(&pArgs->pszMachineName); GOTO_CLEANUP_ON_WINERROR(dwError); } if (!pArgs->pszOsName || !pArgs->pszOsVersion || !pArgs->pszOsServicePack) { dwError = GetOsInfo( pArgs->pszOsName ? NULL : &pArgs->pszOsName, pArgs->pszOsVersion ? NULL : &pArgs->pszOsVersion, pArgs->pszOsServicePack ? NULL : &pArgs->pszOsServicePack); GOTO_CLEANUP_ON_WINERROR(dwError); } dwError = CleanupUsername(pArgs->pszDomain, &pArgs->pszUsername); GOTO_CLEANUP_ON_WINERROR(dwError); if (!pArgs->pszPassword) { dwError = PromptPassword(pArgs->pszUsername, &pArgs->pszPassword); GOTO_CLEANUP_ON_WINERROR(dwError); } cleanup: if (dwError) { FreeJoinArgsContents(pArgs); } return dwError; }
static DWORD AD_RawFindComputerDn( IN HANDLE hDirectory, IN PCSTR pszDnsDomainName, IN PCSTR pszSamAccountName, OUT PSTR* ppszComputerDn ) { DWORD dwError = 0; LDAP* pLd = NULL; PSTR pszDirectoryRoot = NULL; PSTR pszEscapedSamAccountName = NULL; PSTR szAttributeList[] = {"*", NULL}; PSTR pszQuery = NULL; LDAPMessage *pMessage = NULL; int count = 0; PSTR pszComputerDn = NULL; pLd = LwLdapGetSession(hDirectory); dwError = LwLdapConvertDomainToDN( pszDnsDomainName, &pszDirectoryRoot); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapEscapeString( &pszEscapedSamAccountName, pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); LwStrToUpper(pszEscapedSamAccountName); dwError = LwAllocateStringPrintf( &pszQuery, "(sAMAccountName=%s)", pszEscapedSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapDirectorySearch( hDirectory, pszDirectoryRoot, LDAP_SCOPE_SUBTREE, pszQuery, szAttributeList, &pMessage); BAIL_ON_LSA_ERROR(dwError); count = ldap_count_entries(pLd, pMessage); if (count < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (count == 0) { dwError = LW_ERROR_NO_SUCH_DOMAIN; } else if (count > 1) { dwError = LW_ERROR_DUPLICATE_DOMAINNAME; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetDN(hDirectory, pMessage, &pszComputerDn); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pszComputerDn)) { dwError = LW_ERROR_LDAP_FAILED_GETDN; BAIL_ON_LSA_ERROR(dwError); } error: if (dwError) { LW_SAFE_FREE_STRING(pszComputerDn); } LW_SAFE_FREE_STRING(pszDirectoryRoot); LW_SAFE_FREE_STRING(pszEscapedSamAccountName); LW_SAFE_FREE_STRING(pszQuery); if (pMessage) { ldap_msgfree(pMessage); } *ppszComputerDn = pszComputerDn; return dwError; }
DWORD LocalMarshalEntryToSecurityObject( PDIRECTORY_ENTRY pEntry, PLSA_SECURITY_OBJECT* ppObject ) { DWORD dwError = 0; static WCHAR wszAttrNameObjectClass[] = LOCAL_DIR_ATTR_OBJECT_CLASS; static WCHAR wszAttrNameUID[] = LOCAL_DIR_ATTR_UID; static WCHAR wszAttrNameGID[] = LOCAL_DIR_ATTR_GID; static WCHAR wszAttrNamePrimaryGroup[] = LOCAL_DIR_ATTR_PRIMARY_GROUP; static WCHAR wszAttrNameSamAccountName[] = LOCAL_DIR_ATTR_SAM_ACCOUNT_NAME; static WCHAR wszAttrNamePassword[] = LOCAL_DIR_ATTR_PASSWORD; static WCHAR wszAttrNameNTHash[] = LOCAL_DIR_ATTR_NT_HASH; static WCHAR wszAttrNameLMHash[] = LOCAL_DIR_ATTR_LM_HASH; static WCHAR wszAttrNameGecos[] = LOCAL_DIR_ATTR_GECOS; static WCHAR wszAttrNameShell[] = LOCAL_DIR_ATTR_SHELL; static WCHAR wszAttrNameHomedir[] = LOCAL_DIR_ATTR_HOME_DIR; static WCHAR wszAttrNameUPN[] = LOCAL_DIR_ATTR_USER_PRINCIPAL_NAME; static WCHAR wszAttrNameObjectSID[] = LOCAL_DIR_ATTR_OBJECT_SID; static WCHAR wszAttrNameAccountFlags[] = LOCAL_DIR_ATTR_ACCOUNT_FLAGS; static WCHAR wszAttrNameAccountExpiry[] = LOCAL_DIR_ATTR_ACCOUNT_EXPIRY; static WCHAR wszAttrNamePasswdLastSet[] = LOCAL_DIR_ATTR_PASSWORD_LAST_SET; static WCHAR wszAttrNameDN[] = LOCAL_DIR_ATTR_DISTINGUISHED_NAME; static WCHAR wszAttrNameNetBIOSDomain[] = LOCAL_DIR_ATTR_NETBIOS_NAME; PLSA_SECURITY_OBJECT pObject = NULL; DWORD dwObjectClass = 0; DWORD dwAccountFlags = 0; LONG64 llAccountExpiry = 0; LONG64 llPasswordLastSet = 0; DWORD dwUid = 0; DWORD dwGid = 0; BOOLEAN enableUnixIds = TRUE; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameObjectClass, &dwObjectClass); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateMemory( sizeof(*pObject), OUT_PPVOID(&pObject)); BAIL_ON_LSA_ERROR(dwError); pObject->bIsLocal = TRUE; dwError = LocalCfgGetEnableUnixIds(&enableUnixIds); BAIL_ON_LSA_ERROR(dwError); pObject->enabled = enableUnixIds; switch (dwObjectClass) { case LOCAL_OBJECT_CLASS_USER: pObject->type = LSA_OBJECT_TYPE_USER; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameUID, &dwUid); BAIL_ON_LSA_ERROR(dwError); pObject->userInfo.uid = (uid_t) dwUid; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNamePrimaryGroup, &dwGid); BAIL_ON_LSA_ERROR(dwError); pObject->userInfo.gid = (gid_t) dwGid; dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameSamAccountName, &pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNamePassword, &pObject->userInfo.pszPasswd); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameGecos, &pObject->userInfo.pszGecos); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameShell, &pObject->userInfo.pszShell); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameHomedir, &pObject->userInfo.pszHomedir); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameObjectSID, &pObject->pszObjectSid); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameUPN, &pObject->userInfo.pszUPN); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameDN, &pObject->pszDN); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameNetBIOSDomain, &pObject->pszNetbiosDomainName); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameAccountFlags, &dwAccountFlags); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToLargeInteger( pEntry, wszAttrNameAccountExpiry, &llAccountExpiry); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToLargeInteger( pEntry, wszAttrNamePasswdLastSet, &llPasswordLastSet); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAccountFlagsToSecurityObject( pObject, dwAccountFlags, llPasswordLastSet, llAccountExpiry); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateStringPrintf( &pObject->userInfo.pszUnixName, "%s%c%s", pObject->pszNetbiosDomainName, LsaSrvDomainSeparator(), pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pObject->userInfo.pszUPN)) { dwError = LwAllocateStringPrintf( &pObject->userInfo.pszUPN, "%s@%s", pObject->pszSamAccountName, pObject->pszNetbiosDomainName); BAIL_ON_LSA_ERROR(dwError); LwStrToUpper(pObject->userInfo.pszUPN + strlen(pObject->pszSamAccountName) + 1); pObject->userInfo.bIsGeneratedUPN = TRUE; } dwError = LocalMarshalAttrToOctetStream( pEntry, wszAttrNameNTHash, &pObject->userInfo.pNtHash, &pObject->userInfo.dwNtHashLen); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToOctetStream( pEntry, wszAttrNameLMHash, &pObject->userInfo.pLmHash, &pObject->userInfo.dwLmHashLen); if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); break; case LOCAL_OBJECT_CLASS_GROUP: pObject->type = LSA_OBJECT_TYPE_GROUP; dwError = LocalMarshalAttrToInteger( pEntry, wszAttrNameGID, &dwGid); BAIL_ON_LSA_ERROR(dwError); pObject->groupInfo.gid = dwGid; dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameSamAccountName, &pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameDN, &pObject->pszDN); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameObjectSID, &pObject->pszObjectSid); BAIL_ON_LSA_ERROR(dwError); dwError = LocalMarshalAttrToANSIFromUnicodeString( pEntry, wszAttrNameNetBIOSDomain, &pObject->pszNetbiosDomainName); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateStringPrintf( &pObject->groupInfo.pszUnixName, "%s%c%s", pObject->pszNetbiosDomainName, LsaSrvDomainSeparator(), pObject->pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_LSA_ERROR(dwError); } *ppObject = pObject; cleanup: return dwError; error: *ppObject = NULL; if (pObject) { LsaUtilFreeSecurityObject(pObject); } goto cleanup; }
DWORD ADFindComputerDN( IN PLSA_DM_LDAP_CONNECTION pConn, PCSTR pszSamAccountName, PCSTR pszDomainName, PSTR* ppszComputerDN ) { DWORD dwError = 0; LDAP *pLd = NULL; PSTR pszDirectoryRoot = NULL; PSTR szAttributeList[] = {"*", NULL}; PSTR pszQuery = NULL; LDAPMessage *pMessage = NULL; DWORD dwCount = 0; PSTR pszComputerDN = NULL; PSTR pszEscapedUpperSamAccountName = NULL; HANDLE hDirectory = NULL; dwError = LwLdapConvertDomainToDN(pszDomainName, &pszDirectoryRoot); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapEscapeString( &pszEscapedUpperSamAccountName, pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); LwStrToUpper(pszEscapedUpperSamAccountName); dwError = LwAllocateStringPrintf(&pszQuery, "(sAMAccountName=%s)", pszEscapedUpperSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LsaDmLdapDirectorySearch( pConn, pszDirectoryRoot, LDAP_SCOPE_SUBTREE, pszQuery, szAttributeList, &hDirectory, &pMessage); BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); dwCount = ldap_count_entries( pLd, pMessage ); if (dwCount < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (dwCount == 0) { dwError = LW_ERROR_NO_SUCH_DOMAIN; } else if (dwCount > 1) { dwError = LW_ERROR_DUPLICATE_DOMAINNAME; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetDN( hDirectory, pMessage, &pszComputerDN); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pszComputerDN)) { dwError = LW_ERROR_LDAP_FAILED_GETDN; BAIL_ON_LSA_ERROR(dwError); } *ppszComputerDN = pszComputerDN; cleanup: LW_SAFE_FREE_STRING(pszEscapedUpperSamAccountName); LW_SAFE_FREE_STRING(pszDirectoryRoot); LW_SAFE_FREE_STRING(pszQuery); if (pMessage) { ldap_msgfree(pMessage); } return dwError; error: *ppszComputerDN = NULL; LW_SAFE_FREE_STRING(pszComputerDN); goto cleanup; }