svn commit: samba r17158 - in branches: SAMBA_3_0/source/utils SAMBA_3_0_23/source/utils

jerry at samba.org jerry at samba.org
Thu Jul 20 14:39:06 GMT 2006


Author: jerry
Date: 2006-07-20 14:39:06 +0000 (Thu, 20 Jul 2006)
New Revision: 17158

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17158

Log:
Add two new options to 'net ads join'

  * createupn=[host_upn at realm]
  * createcomputer=<ou path top to bottom> (this was previously
    the only arg)


Modified:
   branches/SAMBA_3_0/source/utils/net_ads.c
   branches/SAMBA_3_0_23/source/utils/net_ads.c


Changeset:
Modified: branches/SAMBA_3_0/source/utils/net_ads.c
===================================================================
--- branches/SAMBA_3_0/source/utils/net_ads.c	2006-07-20 14:35:41 UTC (rev 17157)
+++ branches/SAMBA_3_0/source/utils/net_ads.c	2006-07-20 14:39:06 UTC (rev 17158)
@@ -928,7 +928,7 @@
 static ADS_STATUS net_set_machine_spn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s )
 {
 	ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN);
-	char *host_upn, *new_dn;
+	char *new_dn;
 	ADS_MODLIST mods;
 	const char *servicePrincipalName[3] = {NULL, NULL, NULL};
 	char *psp;
@@ -964,9 +964,7 @@
 		return ADS_ERROR(LDAP_NO_MEMORY);
 	}
 
-	/* Windows only creates HOST/shortname & HOST/fqdn.  We create 
-	   the UPN as well so that 'kinit -k' will work.  You can only 
-	   request a TGT for entries with a UPN in AD. */
+	/* Windows only creates HOST/shortname & HOST/fqdn. */
 	   
 	if ( !(psp = talloc_asprintf(ctx, "HOST/%s", machine_name)) ) 
 		goto done;
@@ -979,9 +977,63 @@
 		goto done;
 	servicePrincipalName[1] = psp;
 	
-	if (!(host_upn = talloc_asprintf(ctx, "%s@%s", servicePrincipalName[0], ads_s->config.realm)))
+	if (!(mods = ads_init_mods(ctx))) {
 		goto done;
+	}
+	
+	/* fields of primary importance */
+	
+	ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn);
+	ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
 
+	status = ads_gen_mod(ads_s, new_dn, mods);
+
+done:
+	ads_msgfree(ads_s, res);
+	
+	return status;
+}
+
+/*******************************************************************
+ Set a machines dNSHostName and servicePrincipalName attributes
+ ********************************************************************/
+
+static ADS_STATUS net_set_machine_upn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s, const char *upn )
+{
+	ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN);
+	char *new_dn;
+	ADS_MODLIST mods;
+	LDAPMessage *res = NULL;
+	char *dn_string = NULL;
+	const char *machine_name = global_myname();
+	int count;
+	
+	if ( !machine_name ) {
+		return ADS_ERROR(LDAP_NO_MEMORY);
+	}
+	
+	/* Find our DN */
+	
+	status = ads_find_machine_acct(ads_s, (void **)(void *)&res, machine_name);
+	if (!ADS_ERR_OK(status)) 
+		return status;
+		
+	if ( (count = ads_count_replies(ads_s, res)) != 1 ) {
+		DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count));
+		return ADS_ERROR(LDAP_NO_MEMORY);	
+	}
+	
+	if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) {
+		DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n"));
+		goto done;
+	}
+	
+	new_dn = talloc_strdup(ctx, dn_string);
+	ads_memfree(ads_s, dn_string);
+	if (!new_dn) {
+		return ADS_ERROR(LDAP_NO_MEMORY);
+	}
+	
 	/* now do the mods */
 	
 	if (!(mods = ads_init_mods(ctx))) {
@@ -990,8 +1042,7 @@
 	
 	/* fields of primary importance */
 	
-	ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn);
-	ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
+	ads_mod_str(ctx, &mods, "userPrincipalName", upn);
 
 	status = ads_gen_mod(ads_s, new_dn, mods);
 
@@ -1001,7 +1052,6 @@
 	return status;
 }
 
-
 /*******************************************************************
   join a domain using ADS (LDAP mods)
  ********************************************************************/
@@ -1089,6 +1139,19 @@
 	return kerberos_secrets_store_des_salt( salt );
 }
 
+/*********************************************************
+ utility function to parse an integer parameter from 
+ "parameter = value"
+**********************************************************/
+static char* get_string_param( const char* param )
+{
+	char *p;
+	
+	if ( (p = strchr( param, '=' )) == NULL )
+		return NULL;
+		
+	return (p+1);
+}
 /*******************************************************************
   join a domain using ADS (LDAP mods)
  ********************************************************************/
@@ -1103,6 +1166,10 @@
 	struct cldap_netlogon_reply cldap_reply;
 	TALLOC_CTX *ctx;
 	DOM_SID *domain_sid = NULL;
+	BOOL createupn = False;
+	const char *machineupn = NULL;
+	const char *create_in_ou = NULL;
+	int i;
 	
 	if ( check_ads_config() != 0 ) {
 		d_fprintf(stderr, "Invalid configuration.  Exiting....\n");
@@ -1126,11 +1193,30 @@
 		return -1;
 	}
 
-	/* If we were given an OU, try to create the machine in the OU account 
-	   first and then do the normal RPC join */
+	/* process additional command line args */
+	
+	for ( i=0; i<argc; i++ ) {
+		if ( !StrnCaseCmp(argv[i], "createupn", strlen("createupn")) ) {
+			createupn = True;
+			machineupn = get_string_param(argv[i]);
+		}
+		else if ( !StrnCaseCmp(argv[i], "createcomputer", strlen("createcomputer")) ) {
+			if ( (create_in_ou = get_string_param(argv[i])) == NULL ) {
+				d_fprintf(stderr, "Please supply a valid OU path\n");
+				return -1;
+			}		
+		}
+		else {
+			d_fprintf(stderr, "Bad option: %s\n", argv[i]);
+			return -1;
+		}
+	}
 
-	if ( argc > 0 ) {
-		status = net_precreate_machine_acct( ads, argv[0] );
+	/* If we were given an OU, try to create the machine in 
+	   the OU account first and then do the normal RPC join */
+
+	if  ( create_in_ou ) {
+		status = net_precreate_machine_acct( ads, create_in_ou );
 		if ( !ADS_ERR_OK(status) ) {
 			d_fprintf( stderr, "Failed to pre-create the machine object "
 				"in OU %s.\n", argv[0]);
@@ -1218,6 +1304,22 @@
 		return -1;
 	}
 
+	if ( createupn ) {
+		pstring upn;
+		
+		/* default to using the short UPN name */
+		if ( !machineupn ) {
+			snprintf( upn, sizeof(upn), "host/%s@%s", global_myname(), 
+				ads->config.realm );
+			machineupn = upn;
+		}
+		
+		status = net_set_machine_upn( ctx, ads, machineupn );
+		if ( !ADS_ERR_OK(status) )  {
+			d_fprintf(stderr, "Failed to set userPrincipalName.  Are you a Domain Admin?\n");
+		}
+	}
+
 	/* 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"));

Modified: branches/SAMBA_3_0_23/source/utils/net_ads.c
===================================================================
--- branches/SAMBA_3_0_23/source/utils/net_ads.c	2006-07-20 14:35:41 UTC (rev 17157)
+++ branches/SAMBA_3_0_23/source/utils/net_ads.c	2006-07-20 14:39:06 UTC (rev 17158)
@@ -928,7 +928,7 @@
 static ADS_STATUS net_set_machine_spn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s )
 {
 	ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN);
-	char *host_upn, *new_dn;
+	char *new_dn;
 	ADS_MODLIST mods;
 	const char *servicePrincipalName[3] = {NULL, NULL, NULL};
 	char *psp;
@@ -964,9 +964,7 @@
 		return ADS_ERROR(LDAP_NO_MEMORY);
 	}
 
-	/* Windows only creates HOST/shortname & HOST/fqdn.  We create 
-	   the UPN as well so that 'kinit -k' will work.  You can only 
-	   request a TGT for entries with a UPN in AD. */
+	/* Windows only creates HOST/shortname & HOST/fqdn. */
 	   
 	if ( !(psp = talloc_asprintf(ctx, "HOST/%s", machine_name)) ) 
 		goto done;
@@ -979,9 +977,63 @@
 		goto done;
 	servicePrincipalName[1] = psp;
 	
-	if (!(host_upn = talloc_asprintf(ctx, "%s@%s", servicePrincipalName[0], ads_s->config.realm)))
+	if (!(mods = ads_init_mods(ctx))) {
 		goto done;
+	}
+	
+	/* fields of primary importance */
+	
+	ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn);
+	ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
 
+	status = ads_gen_mod(ads_s, new_dn, mods);
+
+done:
+	ads_msgfree(ads_s, res);
+	
+	return status;
+}
+
+/*******************************************************************
+ Set a machines dNSHostName and servicePrincipalName attributes
+ ********************************************************************/
+
+static ADS_STATUS net_set_machine_upn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s, const char *upn )
+{
+	ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN);
+	char *new_dn;
+	ADS_MODLIST mods;
+	LDAPMessage *res = NULL;
+	char *dn_string = NULL;
+	const char *machine_name = global_myname();
+	int count;
+	
+	if ( !machine_name ) {
+		return ADS_ERROR(LDAP_NO_MEMORY);
+	}
+	
+	/* Find our DN */
+	
+	status = ads_find_machine_acct(ads_s, (void **)(void *)&res, machine_name);
+	if (!ADS_ERR_OK(status)) 
+		return status;
+		
+	if ( (count = ads_count_replies(ads_s, res)) != 1 ) {
+		DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count));
+		return ADS_ERROR(LDAP_NO_MEMORY);	
+	}
+	
+	if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) {
+		DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n"));
+		goto done;
+	}
+	
+	new_dn = talloc_strdup(ctx, dn_string);
+	ads_memfree(ads_s, dn_string);
+	if (!new_dn) {
+		return ADS_ERROR(LDAP_NO_MEMORY);
+	}
+	
 	/* now do the mods */
 	
 	if (!(mods = ads_init_mods(ctx))) {
@@ -990,8 +1042,7 @@
 	
 	/* fields of primary importance */
 	
-	ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn);
-	ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
+	ads_mod_str(ctx, &mods, "userPrincipalName", upn);
 
 	status = ads_gen_mod(ads_s, new_dn, mods);
 
@@ -1001,7 +1052,6 @@
 	return status;
 }
 
-
 /*******************************************************************
   join a domain using ADS (LDAP mods)
  ********************************************************************/
@@ -1089,6 +1139,19 @@
 	return kerberos_secrets_store_des_salt( salt );
 }
 
+/*********************************************************
+ utility function to parse an integer parameter from 
+ "parameter = value"
+**********************************************************/
+static char* get_string_param( const char* param )
+{
+	char *p;
+	
+	if ( (p = strchr( param, '=' )) == NULL )
+		return NULL;
+		
+	return (p+1);
+}
 /*******************************************************************
   join a domain using ADS (LDAP mods)
  ********************************************************************/
@@ -1103,6 +1166,10 @@
 	struct cldap_netlogon_reply cldap_reply;
 	TALLOC_CTX *ctx;
 	DOM_SID *domain_sid = NULL;
+	BOOL createupn = False;
+	const char *machineupn = NULL;
+	const char *create_in_ou = NULL;
+	int i;
 	
 	if ( check_ads_config() != 0 ) {
 		d_fprintf(stderr, "Invalid configuration.  Exiting....\n");
@@ -1126,11 +1193,30 @@
 		return -1;
 	}
 
-	/* If we were given an OU, try to create the machine in the OU account 
-	   first and then do the normal RPC join */
+	/* process additional command line args */
+	
+	for ( i=0; i<argc; i++ ) {
+		if ( !StrnCaseCmp(argv[i], "createupn", strlen("createupn")) ) {
+			createupn = True;
+			machineupn = get_string_param(argv[i]);
+		}
+		else if ( !StrnCaseCmp(argv[i], "createcomputer", strlen("createcomputer")) ) {
+			if ( (create_in_ou = get_string_param(argv[i])) == NULL ) {
+				d_fprintf(stderr, "Please supply a valid OU path\n");
+				return -1;
+			}		
+		}
+		else {
+			d_fprintf(stderr, "Bad option: %s\n", argv[i]);
+			return -1;
+		}
+	}
 
-	if ( argc > 0 ) {
-		status = net_precreate_machine_acct( ads, argv[0] );
+	/* If we were given an OU, try to create the machine in 
+	   the OU account first and then do the normal RPC join */
+
+	if  ( create_in_ou ) {
+		status = net_precreate_machine_acct( ads, create_in_ou );
 		if ( !ADS_ERR_OK(status) ) {
 			d_fprintf( stderr, "Failed to pre-create the machine object "
 				"in OU %s.\n", argv[0]);
@@ -1218,6 +1304,22 @@
 		return -1;
 	}
 
+	if ( createupn ) {
+		pstring upn;
+		
+		/* default to using the short UPN name */
+		if ( !machineupn ) {
+			snprintf( upn, sizeof(upn), "host/%s@%s", global_myname(), 
+				ads->config.realm );
+			machineupn = upn;
+		}
+		
+		status = net_set_machine_upn( ctx, ads, machineupn );
+		if ( !ADS_ERR_OK(status) )  {
+			d_fprintf(stderr, "Failed to set userPrincipalName.  Are you a Domain Admin?\n");
+		}
+	}
+
 	/* 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"));



More information about the samba-cvs mailing list