"\tHas a hardware clock: %s\n"
"\tIs a non-domain NC serviced by LDAP server: %s\n"
"\tIs NT6 DC that has some secrets: %s\n"
- "\tIs NT6 DC that has all secrets: %s\n"),
+ "\tIs NT6 DC that has all secrets: %s\n"
+ "\tRuns Active Directory Web Services: %s\n"
+ "\tRuns on Windows 2012 or later: %s\n"),
(reply.server_type & NBT_SERVER_PDC) ? _("yes") : _("no"),
(reply.server_type & NBT_SERVER_GC) ? _("yes") : _("no"),
(reply.server_type & NBT_SERVER_LDAP) ? _("yes") : _("no"),
(reply.server_type & NBT_SERVER_GOOD_TIMESERV) ? _("yes") : _("no"),
(reply.server_type & NBT_SERVER_NDNC) ? _("yes") : _("no"),
(reply.server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6) ? _("yes") : _("no"),
- (reply.server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6) ? _("yes") : _("no"));
+ (reply.server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6) ? _("yes") : _("no"),
+ (reply.server_type & NBT_SERVER_ADS_WEB_SERVICE) ? _("yes") : _("no"),
+ (reply.server_type & NBT_SERVER_DS_8) ? _("yes") : _("no"));
printf(_("Forest:\t\t\t%s\n"), reply.forest);
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
DNS_ERROR dns_err;
fstring dns_server;
- const char *dns_hosts_file;
const char *dnsdomain = NULL;
char *root_domain = NULL;
}
dnsdomain++;
- dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
- status = ads_dns_lookup_ns(ctx, dns_hosts_file,
- dnsdomain, &nameservers, &ns_count);
+ status = ads_dns_lookup_ns(ctx,
+ dnsdomain,
+ &nameservers,
+ &ns_count);
if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {
/* Child domains often do not have NS records. Look
for the NS record for the forest root domain
/* try again for NS servers */
- status = ads_dns_lookup_ns(ctx, dns_hosts_file, root_domain,
- &nameservers, &ns_count);
+ status = ads_dns_lookup_ns(ctx,
+ root_domain,
+ &nameservers,
+ &ns_count);
if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {
DEBUG(3,("net_update_dns_internal: Failed to find name server for the %s "
" Also, the operatingSystemService attribute is also set when along with\n"
" the two other attributes.\n"));
+ d_printf(_(" osServicePack=string Set the operatingSystemServicePack "
+ "attribute during the join. Note: if not specified then by "
+ "default the samba version string is used instead.\n"));
return -1;
}
int i;
const char *os_name = NULL;
const char *os_version = NULL;
+ const char *os_servicepack = NULL;
bool modify_config = lp_config_backend_is_registry();
if (c->display_usage)
goto fail;
}
}
+ else if ( !strncasecmp_m(argv[i], "osServicePack", strlen("osServicePack")) ) {
+ if ( (os_servicepack = get_string_param(argv[i])) == NULL ) {
+ d_fprintf(stderr, _("Please supply a valid servicepack identifier.\n"));
+ werr = WERR_INVALID_PARAM;
+ goto fail;
+ }
+ }
else if ( !strncasecmp_m(argv[i], "machinepass", strlen("machinepass")) ) {
if ( (machine_password = get_string_param(argv[i])) == NULL ) {
d_fprintf(stderr, _("Please supply a valid password to set as trust account password.\n"));
r->in.account_ou = create_in_ou;
r->in.os_name = os_name;
r->in.os_version = os_version;
+ r->in.os_servicepack = os_servicepack;
r->in.dc_name = c->opt_host;
r->in.admin_account = c->opt_user_name;
r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
return ret;
}
-static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **argv)
+static int net_ads_kerberos_pac_common(struct net_context *c, int argc, const char **argv,
+ struct PAC_DATA_CTR **pac_data_ctr)
{
- struct PAC_LOGON_INFO *info = NULL;
- TALLOC_CTX *mem_ctx = NULL;
NTSTATUS status;
int ret = -1;
const char *impersonate_princ_s = NULL;
const char *local_service = NULL;
+ int i;
- if (c->display_usage) {
- d_printf( "%s\n"
- "net ads kerberos pac [impersonation_principal]\n"
- " %s\n",
- _("Usage:"),
- _("Dump the Kerberos PAC"));
- return 0;
- }
-
- mem_ctx = talloc_init("net_ads_kerberos_pac");
- if (!mem_ctx) {
- goto out;
- }
-
- if (argc > 0) {
- impersonate_princ_s = argv[0];
+ for (i=0; i<argc; i++) {
+ if (strnequal(argv[i], "impersonate", strlen("impersonate"))) {
+ impersonate_princ_s = get_string_param(argv[i]);
+ if (impersonate_princ_s == NULL) {
+ return -1;
+ }
+ }
+ if (strnequal(argv[i], "local_service", strlen("local_service"))) {
+ local_service = get_string_param(argv[i]);
+ if (local_service == NULL) {
+ return -1;
+ }
+ }
}
- local_service = talloc_asprintf(mem_ctx, "%s$@%s",
- lp_netbios_name(), lp_realm());
if (local_service == NULL) {
- goto out;
+ local_service = talloc_asprintf(c, "%s$@%s",
+ lp_netbios_name(), lp_realm());
+ if (local_service == NULL) {
+ goto out;
+ }
}
c->opt_password = net_prompt_pass(c, c->opt_user_name);
- status = kerberos_return_pac(mem_ctx,
+ status = kerberos_return_pac(c,
c->opt_user_name,
c->opt_password,
0,
2592000, /* one month */
impersonate_princ_s,
local_service,
- &info);
+ pac_data_ctr);
if (!NT_STATUS_IS_OK(status)) {
d_printf(_("failed to query kerberos PAC: %s\n"),
nt_errstr(status));
goto out;
}
- if (info) {
- const char *s;
- s = NDR_PRINT_STRUCT_STRING(mem_ctx, PAC_LOGON_INFO, info);
- d_printf(_("The Pac: %s\n"), s);
- }
-
ret = 0;
out:
- TALLOC_FREE(mem_ctx);
return ret;
}
+static int net_ads_kerberos_pac_dump(struct net_context *c, int argc, const char **argv)
+{
+ struct PAC_DATA_CTR *pac_data_ctr = NULL;
+ int i;
+ int ret = -1;
+ enum PAC_TYPE type = 0;
+
+ if (c->display_usage) {
+ d_printf( "%s\n"
+ "net ads kerberos pac dump [impersonate=string] [local_service=string] [pac_buffer_type=int]\n"
+ " %s\n",
+ _("Usage:"),
+ _("Dump the Kerberos PAC"));
+ return -1;
+ }
+
+ for (i=0; i<argc; i++) {
+ if (strnequal(argv[i], "pac_buffer_type", strlen("pac_buffer_type"))) {
+ type = get_int_param(argv[i]);
+ }
+ }
+
+ ret = net_ads_kerberos_pac_common(c, argc, argv, &pac_data_ctr);
+ if (ret) {
+ return ret;
+ }
+
+ if (type == 0) {
+
+ char *s = NULL;
+
+ s = NDR_PRINT_STRUCT_STRING(c, PAC_DATA,
+ pac_data_ctr->pac_data);
+ if (s != NULL) {
+ d_printf(_("The Pac: %s\n"), s);
+ talloc_free(s);
+ }
+
+ return 0;
+ }
+
+ for (i=0; i < pac_data_ctr->pac_data->num_buffers; i++) {
+
+ char *s = NULL;
+
+ if (pac_data_ctr->pac_data->buffers[i].type != type) {
+ continue;
+ }
+
+ s = NDR_PRINT_UNION_STRING(c, PAC_INFO, type,
+ pac_data_ctr->pac_data->buffers[i].info);
+ if (s != NULL) {
+ d_printf(_("The Pac: %s\n"), s);
+ talloc_free(s);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int net_ads_kerberos_pac_save(struct net_context *c, int argc, const char **argv)
+{
+ struct PAC_DATA_CTR *pac_data_ctr = NULL;
+ char *filename = NULL;
+ int ret = -1;
+ int i;
+
+ if (c->display_usage) {
+ d_printf( "%s\n"
+ "net ads kerberos pac save [impersonate=string] [local_service=string] [filename=string]\n"
+ " %s\n",
+ _("Usage:"),
+ _("Save the Kerberos PAC"));
+ return -1;
+ }
+
+ for (i=0; i<argc; i++) {
+ if (strnequal(argv[i], "filename", strlen("filename"))) {
+ filename = get_string_param(argv[i]);
+ if (filename == NULL) {
+ return -1;
+ }
+ }
+ }
+
+ ret = net_ads_kerberos_pac_common(c, argc, argv, &pac_data_ctr);
+ if (ret) {
+ return ret;
+ }
+
+ if (filename == NULL) {
+ d_printf(_("please define \"filename=<filename>\" to save the PAC\n"));
+ return -1;
+ }
+
+ /* save the raw format */
+ if (!file_save(filename, pac_data_ctr->pac_blob.data, pac_data_ctr->pac_blob.length)) {
+ d_printf(_("failed to save PAC in %s\n"), filename);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **argv)
+{
+ struct functable func[] = {
+ {
+ "dump",
+ net_ads_kerberos_pac_dump,
+ NET_TRANSPORT_ADS,
+ N_("Dump Kerberos PAC"),
+ N_("net ads kerberos pac dump\n"
+ " Dump a Kerberos PAC to stdout")
+ },
+ {
+ "save",
+ net_ads_kerberos_pac_save,
+ NET_TRANSPORT_ADS,
+ N_("Save Kerberos PAC"),
+ N_("net ads kerberos pac save\n"
+ " Save a Kerberos PAC in a file")
+ },
+
+ {NULL, NULL, 0, NULL, NULL}
+ };
+
+ return net_run_function(c, argc, argv, "net ads kerberos pac", func);
+}
+
static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char **argv)
{
TALLOC_CTX *mem_ctx = NULL;
return net_run_function(c, argc, argv, "net ads kerberos", func);
}
+static int net_ads_enctype_lookup_account(struct net_context *c,
+ ADS_STRUCT *ads,
+ const char *account,
+ LDAPMessage **res,
+ const char **enctype_str)
+{
+ const char *filter;
+ const char *attrs[] = {
+ "msDS-SupportedEncryptionTypes",
+ NULL
+ };
+ int count;
+ int ret = -1;
+ ADS_STATUS status;
+
+ filter = talloc_asprintf(c, "(&(objectclass=user)(sAMAccountName=%s))",
+ account);
+ if (filter == NULL) {
+ goto done;
+ }
+
+ status = ads_search(ads, res, filter, attrs);
+ if (!ADS_ERR_OK(status)) {
+ d_printf(_("no account found with filter: %s\n"), filter);
+ goto done;
+ }
+
+ count = ads_count_replies(ads, *res);
+ switch (count) {
+ case 1:
+ break;
+ case 0:
+ d_printf(_("no account found with filter: %s\n"), filter);
+ goto done;
+ default:
+ d_printf(_("multiple accounts found with filter: %s\n"), filter);
+ goto done;
+ }
+
+ if (enctype_str) {
+ *enctype_str = ads_pull_string(ads, c, *res,
+ "msDS-SupportedEncryptionTypes");
+ if (*enctype_str == NULL) {
+ d_printf(_("no msDS-SupportedEncryptionTypes attribute found\n"));
+ goto done;
+ }
+ }
+
+ ret = 0;
+ done:
+ return ret;
+}
+
+static void net_ads_enctype_dump_enctypes(const char *username,
+ const char *enctype_str)
+{
+ int enctypes = atoi(enctype_str);
+
+ d_printf(_("'%s' uses \"msDS-SupportedEncryptionTypes\": %d (0x%08x)\n"),
+ username, enctypes, enctypes);
+
+ printf("[%s] 0x%08x DES-CBC-CRC\n",
+ enctypes & ENC_CRC32 ? "X" : " ",
+ ENC_CRC32);
+ printf("[%s] 0x%08x DES-CBC-MD5\n",
+ enctypes & ENC_RSA_MD5 ? "X" : " ",
+ ENC_RSA_MD5);
+ printf("[%s] 0x%08x RC4-HMAC\n",
+ enctypes & ENC_RC4_HMAC_MD5 ? "X" : " ",
+ ENC_RC4_HMAC_MD5);
+ printf("[%s] 0x%08x AES128-CTS-HMAC-SHA1-96\n",
+ enctypes & ENC_HMAC_SHA1_96_AES128 ? "X" : " ",
+ ENC_HMAC_SHA1_96_AES128);
+ printf("[%s] 0x%08x AES256-CTS-HMAC-SHA1-96\n",
+ enctypes & ENC_HMAC_SHA1_96_AES256 ? "X" : " ",
+ ENC_HMAC_SHA1_96_AES256);
+}
+
+static int net_ads_enctypes_list(struct net_context *c, int argc, const char **argv)
+{
+ int ret = -1;
+ ADS_STATUS status;
+ ADS_STRUCT *ads = NULL;
+ LDAPMessage *res = NULL;
+ const char *str = NULL;
+
+ if (c->display_usage || (argc < 1)) {
+ d_printf( "%s\n"
+ "net ads enctypes list\n"
+ " %s\n",
+ _("Usage:"),
+ _("List supported enctypes"));
+ return 0;
+ }
+
+ status = ads_startup(c, false, &ads);
+ if (!ADS_ERR_OK(status)) {
+ printf("startup failed\n");
+ return ret;
+ }
+
+ ret = net_ads_enctype_lookup_account(c, ads, argv[0], &res, &str);
+ if (ret) {
+ goto done;
+ }
+
+ net_ads_enctype_dump_enctypes(argv[0], str);
+
+ ret = 0;
+ done:
+ ads_msgfree(ads, res);
+ ads_destroy(&ads);
+
+ return ret;
+}
+
+static int net_ads_enctypes_set(struct net_context *c, int argc, const char **argv)
+{
+ int ret = -1;
+ ADS_STATUS status;
+ ADS_STRUCT *ads;
+ LDAPMessage *res = NULL;
+ const char *etype_list_str;
+ const char *dn;
+ ADS_MODLIST mods;
+ uint32_t etype_list;
+ const char *str;
+
+ if (c->display_usage || argc < 1) {
+ d_printf( "%s\n"
+ "net ads enctypes set <sAMAccountName> [enctypes]\n"
+ " %s\n",
+ _("Usage:"),
+ _("Set supported enctypes"));
+ return 0;
+ }
+
+ status = ads_startup(c, false, &ads);
+ if (!ADS_ERR_OK(status)) {
+ printf("startup failed\n");
+ return ret;
+ }
+
+ ret = net_ads_enctype_lookup_account(c, ads, argv[0], &res, NULL);
+ if (ret) {
+ goto done;
+ }
+
+ dn = ads_get_dn(ads, c, res);
+ if (dn == NULL) {
+ goto done;
+ }
+
+ etype_list = ENC_CRC32 | ENC_RSA_MD5 | ENC_RC4_HMAC_MD5;
+#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
+ etype_list |= ENC_HMAC_SHA1_96_AES128;
+#endif
+#ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96
+ etype_list |= ENC_HMAC_SHA1_96_AES256;
+#endif
+
+ if (argv[1] != NULL) {
+ sscanf(argv[1], "%i", &etype_list);
+ }
+
+ etype_list_str = talloc_asprintf(c, "%d", etype_list);
+ if (!etype_list_str) {
+ goto done;
+ }
+
+ mods = ads_init_mods(c);
+ if (!mods) {
+ goto done;
+ }
+
+ status = ads_mod_str(c, &mods, "msDS-SupportedEncryptionTypes",
+ etype_list_str);
+ if (!ADS_ERR_OK(status)) {
+ goto done;
+ }
+
+ status = ads_gen_mod(ads, dn, mods);
+ if (!ADS_ERR_OK(status)) {
+ d_printf(_("failed to add msDS-SupportedEncryptionTypes: %s\n"),
+ ads_errstr(status));
+ goto done;
+ }
+
+ ads_msgfree(ads, res);
+
+ ret = net_ads_enctype_lookup_account(c, ads, argv[0], &res, &str);
+ if (ret) {
+ goto done;
+ }
+
+ net_ads_enctype_dump_enctypes(argv[0], str);
+
+ ret = 0;
+ done:
+ ads_msgfree(ads, res);
+ ads_destroy(&ads);
+
+ return ret;
+}
+
+static int net_ads_enctypes_delete(struct net_context *c, int argc, const char **argv)
+{
+ int ret = -1;
+ ADS_STATUS status;
+ ADS_STRUCT *ads;
+ LDAPMessage *res = NULL;
+ const char *dn;
+ ADS_MODLIST mods;
+
+ if (c->display_usage || argc < 1) {
+ d_printf( "%s\n"
+ "net ads enctypes delete <sAMAccountName>\n"
+ " %s\n",
+ _("Usage:"),
+ _("Delete supported enctypes"));
+ return 0;
+ }
+
+ status = ads_startup(c, false, &ads);
+ if (!ADS_ERR_OK(status)) {
+ printf("startup failed\n");
+ return ret;
+ }
+
+ ret = net_ads_enctype_lookup_account(c, ads, argv[0], &res, NULL);
+ if (ret) {
+ goto done;
+ }
+
+ dn = ads_get_dn(ads, c, res);
+ if (dn == NULL) {
+ goto done;
+ }
+
+ mods = ads_init_mods(c);
+ if (!mods) {
+ goto done;
+ }
+
+ status = ads_mod_str(c, &mods, "msDS-SupportedEncryptionTypes", NULL);
+ if (!ADS_ERR_OK(status)) {
+ goto done;
+ }
+
+ status = ads_gen_mod(ads, dn, mods);
+ if (!ADS_ERR_OK(status)) {
+ d_printf(_("failed to remove msDS-SupportedEncryptionTypes: %s\n"),
+ ads_errstr(status));
+ goto done;
+ }
+
+ ret = 0;
+
+ done:
+ ads_msgfree(ads, res);
+ ads_destroy(&ads);
+ return ret;
+}
+
+static int net_ads_enctypes(struct net_context *c, int argc, const char **argv)
+{
+ struct functable func[] = {
+ {
+ "list",
+ net_ads_enctypes_list,
+ NET_TRANSPORT_ADS,
+ N_("List the supported encryption types"),
+ N_("net ads enctypes list\n"
+ " List the supported encryption types")
+ },
+ {
+ "set",
+ net_ads_enctypes_set,
+ NET_TRANSPORT_ADS,
+ N_("Set the supported encryption types"),
+ N_("net ads enctypes set\n"
+ " Set the supported encryption types")
+ },
+ {
+ "delete",
+ net_ads_enctypes_delete,
+ NET_TRANSPORT_ADS,
+ N_("Delete the supported encryption types"),
+ N_("net ads enctypes delete\n"
+ " Delete the supported encryption types")
+ },
+
+ {NULL, NULL, 0, NULL, NULL}
+ };
+
+ return net_run_function(c, argc, argv, "net ads enctypes", func);
+}
+
+
int net_ads(struct net_context *c, int argc, const char **argv)
{
struct functable func[] = {
N_("net ads kerberos\n"
" Manage kerberos keytab")
},
+ {
+ "enctypes",
+ net_ads_enctypes,
+ NET_TRANSPORT_ADS,
+ N_("List/modify supported encryption types"),
+ N_("net ads enctypes\n"
+ " List/modify enctypes")
+ },
{NULL, NULL, 0, NULL, NULL}
};