static WERROR nt_printer_guid_retrieve_internal(ADS_STRUCT *ads, const char *printer_dn, struct GUID *pguid) { ADS_STATUS ads_status; LDAPMessage *res; const char *attrs[] = {"objectGUID", NULL}; struct GUID guid; bool ok; ads_status = ads_search_dn(ads, &res, printer_dn, attrs); if (!ADS_ERR_OK(ads_status)) { DEBUG(2, ("Failed to retrieve GUID from DC - %s\n", ads_errstr(ads_status))); return WERR_BADFILE; } ZERO_STRUCT(guid); ok = ads_pull_guid(ads, res, &guid); ads_msgfree(ads, res); if (!ok) { return WERR_NOMEM; } *pguid = guid; return WERR_OK; }
/* join a domain using ADS */ int net_ads_join(int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS rc; char *password; char *machine_account = NULL; char *tmp_password; const char *org_unit = "Computers"; char *dn; void *res; DOM_SID dom_sid; char *ou_str; uint32 sec_channel_type = SEC_CHAN_WKSTA; uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT; const char *short_domain_name = NULL; TALLOC_CTX *ctx = NULL; if (argc > 0) { org_unit = argv[0]; } if (!secrets_init()) { DEBUG(1,("Failed to initialise secrets database\n")); return -1; } tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); password = strdup(tmp_password); if (!(ads = ads_startup())) { return -1; } if (!*lp_realm()) { d_printf("realm must be set in in smb.conf for ADS join to succeed.\n"); ads_destroy(&ads); return -1; } if (strcmp(ads->config.realm, lp_realm()) != 0) { d_printf("realm of remote server (%s) and realm in smb.conf (%s) DO NOT match. Aborting join\n", ads->config.realm, lp_realm()); ads_destroy(&ads); return -1; } ou_str = ads_ou_string(org_unit); asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path); free(ou_str); rc = ads_search_dn(ads, &res, dn, NULL); ads_msgfree(ads, res); if (rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) { d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n", org_unit, dn); ads_destroy(&ads); return -1; } free(dn); if (!ADS_ERR_OK(rc)) { d_printf("ads_join_realm: %s\n", ads_errstr(rc)); ads_destroy(&ads); return -1; } rc = ads_join_realm(ads, global_myname(), account_type, org_unit); if (!ADS_ERR_OK(rc)) { d_printf("ads_join_realm: %s\n", ads_errstr(rc)); ads_destroy(&ads); return -1; } rc = ads_domain_sid(ads, &dom_sid); if (!ADS_ERR_OK(rc)) { d_printf("ads_domain_sid: %s\n", ads_errstr(rc)); ads_destroy(&ads); return -1; } if (asprintf(&machine_account, "%s$", global_myname()) == -1) { d_printf("asprintf failed\n"); ads_destroy(&ads); return -1; } rc = ads_set_machine_password(ads, machine_account, password); if (!ADS_ERR_OK(rc)) { d_printf("ads_set_machine_password: %s\n", ads_errstr(rc)); ads_destroy(&ads); return -1; } /* make sure we get the right workgroup */ if ( !(ctx = talloc_init("net ads join")) ) { d_printf("talloc_init() failed!\n"); ads_destroy(&ads); return -1; } rc = ads_workgroup_name(ads, ctx, &short_domain_name); if ( ADS_ERR_OK(rc) ) { if ( !strequal(lp_workgroup(), short_domain_name) ) { d_printf("The workgroup in smb.conf does not match the short\n"); d_printf("domain name obtained from the server.\n"); d_printf("Using the name [%s] from the server.\n", short_domain_name); d_printf("You should set \"workgroup = %s\" in smb.conf.\n", short_domain_name); } } else { short_domain_name = lp_workgroup(); } d_printf("Using short domain name -- %s\n", short_domain_name); /* HACK ALRET! Store the sid and password under bother the lp_workgroup() value from smb.conf and the string returned from the server. The former is neede to bootstrap winbindd's first connection to the DC to get the real short domain name --jerry */ if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) { DEBUG(1,("Failed to save domain sid\n")); ads_destroy(&ads); return -1; } if (!secrets_store_machine_password(password, lp_workgroup(), sec_channel_type)) { DEBUG(1,("Failed to save machine password\n")); ads_destroy(&ads); return -1; } if (!secrets_store_domain_sid(short_domain_name, &dom_sid)) { DEBUG(1,("Failed to save domain sid\n")); ads_destroy(&ads); return -1; } if (!secrets_store_machine_password(password, short_domain_name, sec_channel_type)) { DEBUG(1,("Failed to save machine password\n")); ads_destroy(&ads); return -1; } /* Now build the keytab, using the same ADS connection */ if (lp_use_kerberos_keytab() && ads_keytab_create_default(ads)) { DEBUG(1,("Error creating host keytab!\n")); } d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm); SAFE_FREE(password); SAFE_FREE(machine_account); if ( ctx ) { talloc_destroy(ctx); } ads_destroy(&ads); return 0; }
static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx, ADS_STRUCT *ads, struct spoolss_PrinterInfo2 *pinfo2) { ADS_STATUS ads_rc; LDAPMessage *res; char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped; char *srv_dn_utf8, **srv_cn_utf8; TALLOC_CTX *ctx; ADS_MODLIST mods; const char *attrs[] = {"objectGUID", NULL}; struct GUID guid; WERROR win_rc = WERR_OK; size_t converted_size; const char *printer = pinfo2->sharename; /* build the ads mods */ ctx = talloc_init("nt_printer_publish_ads"); if (ctx == NULL) { return WERR_NOMEM; } DEBUG(5, ("publishing printer %s\n", printer)); /* figure out where to publish */ ads_find_machine_acct(ads, &res, lp_netbios_name()); /* We use ldap_get_dn here as we need the answer * in utf8 to call ldap_explode_dn(). JRA. */ srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res); if (!srv_dn_utf8) { TALLOC_FREE(ctx); return WERR_SERVER_UNAVAILABLE; } ads_msgfree(ads, res); srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1); if (!srv_cn_utf8) { TALLOC_FREE(ctx); ldap_memfree(srv_dn_utf8); return WERR_SERVER_UNAVAILABLE; } /* Now convert to CH_UNIX. */ if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) { TALLOC_FREE(ctx); ldap_memfree(srv_dn_utf8); ldap_memfree(srv_cn_utf8); return WERR_SERVER_UNAVAILABLE; } if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) { TALLOC_FREE(ctx); ldap_memfree(srv_dn_utf8); ldap_memfree(srv_cn_utf8); TALLOC_FREE(srv_dn); return WERR_SERVER_UNAVAILABLE; } ldap_memfree(srv_dn_utf8); ldap_memfree(srv_cn_utf8); srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0); if (!srv_cn_escaped) { TALLOC_FREE(ctx); return WERR_SERVER_UNAVAILABLE; } sharename_escaped = escape_rdn_val_string_alloc(printer); if (!sharename_escaped) { SAFE_FREE(srv_cn_escaped); TALLOC_FREE(ctx); return WERR_SERVER_UNAVAILABLE; } prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn); SAFE_FREE(srv_cn_escaped); SAFE_FREE(sharename_escaped); mods = ads_init_mods(ctx); if (mods == NULL) { SAFE_FREE(prt_dn); TALLOC_FREE(ctx); return WERR_NOMEM; } ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer); /* publish it */ ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods); if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) { int i; for (i=0; mods[i] != 0; i++) ; mods[i] = (LDAPMod *)-1; ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods); } if (!ADS_ERR_OK(ads_rc)) { DEBUG(3, ("error publishing %s: %s\n", printer, ads_errstr(ads_rc))); } /* retreive the guid and store it locally */ if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) { bool guid_ok; ZERO_STRUCT(guid); guid_ok = ads_pull_guid(ads, res, &guid); ads_msgfree(ads, res); if (guid_ok) { store_printer_guid(msg_ctx, printer, guid); } } TALLOC_FREE(ctx); return win_rc; }