⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldap.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!val)		return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL);	return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES,			       name, (const void **) values);}/** * Perform an ldap modify * @param ads connection to ads server * @param mod_dn DistinguishedName to modify * @param mods list of modifications to perform * @return status of modify **/ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods){	int ret,i;	char *utf8_dn = NULL;	/* 	   this control is needed to modify that contains a currently 	   non-existent attribute (but allowable for the object) to run	*/	LDAPControl PermitModify = {                CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID),		{0, NULL},		(char) 1};	LDAPControl *controls[2];	controls[0] = &PermitModify;	controls[1] = NULL;	if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) {		return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);	}	/* find the end of the list, marked by NULL or -1 */	for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);	/* make sure the end of the list is NULL */	mods[i] = NULL;	ret = ldap_modify_ext_s(ads->ld, utf8_dn,				(LDAPMod **) mods, controls, NULL);	SAFE_FREE(utf8_dn);	return ADS_ERROR(ret);}/** * Perform an ldap add * @param ads connection to ads server * @param new_dn DistinguishedName to add * @param mods list of attributes and values for DN * @return status of add **/ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods){	int ret, i;	char *utf8_dn = NULL;	if (push_utf8_allocate(&utf8_dn, new_dn) == -1) {		DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!"));		return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);	}		/* find the end of the list, marked by NULL or -1 */	for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);	/* make sure the end of the list is NULL */	mods[i] = NULL;	ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods);	SAFE_FREE(utf8_dn);	return ADS_ERROR(ret);}/** * Delete a DistinguishedName * @param ads connection to ads server * @param new_dn DistinguishedName to delete * @return status of delete **/ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn){	int ret;	char *utf8_dn = NULL;	if (push_utf8_allocate(&utf8_dn, del_dn) == -1) {		DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!"));		return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);	}		ret = ldap_delete_s(ads->ld, utf8_dn);	return ADS_ERROR(ret);}/** * Build an org unit string *  if org unit is Computers or blank then assume a container, otherwise *  assume a \ separated list of organisational units * @param ads connection to ads server * @param org_unit Organizational unit * @return org unit string - caller must free **/char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit){	char *ret = NULL;	if (!org_unit || !*org_unit) {		ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS);		/* samba4 might not yet respond to a wellknownobject-query */		return ret ? ret : SMB_STRDUP("cn=Computers");	}		if (strequal(org_unit, "Computers")) {		return SMB_STRDUP("cn=Computers");	}	return ads_build_path(org_unit, "\\/", "ou=", 1);}/** * Get a org unit string for a well-known GUID * @param ads connection to ads server * @param wknguid Well known GUID * @return org unit string - caller must free **/char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid){	ADS_STATUS status;	void *res;	char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp;	const char *attrs[] = {"distinguishedName", NULL};	int new_ln, wkn_ln, bind_ln, i;	if (wknguid == NULL) {		return NULL;	}	if (asprintf(&base, "<WKGUID=%s,%s>", wknguid, ads->config.bind_path ) == -1) {		DEBUG(1, ("asprintf failed!\n"));		return NULL;	}	status = ads_search_dn(ads, &res, base, attrs);	if (!ADS_ERR_OK(status)) {		DEBUG(1,("Failed while searching for: %s\n", base));		return NULL;	}	free(base);	if (ads_count_replies(ads, res) != 1) {		return NULL;	}	/* substitute the bind-path from the well-known-guid-search result */	wkn_dn = ads_get_dn(ads, res);	wkn_dn_exp = ldap_explode_dn(wkn_dn, 0);	bind_dn_exp = ldap_explode_dn(ads->config.bind_path, 0);	for (wkn_ln=0; wkn_dn_exp[wkn_ln]; wkn_ln++)		;	for (bind_ln=0; bind_dn_exp[bind_ln]; bind_ln++)		;	new_ln = wkn_ln - bind_ln;	ret = wkn_dn_exp[0];	for (i=1; i < new_ln; i++) {		char *s;		asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]);		ret = SMB_STRDUP(s);		free(s);	}	return ret;}/** * Adds (appends) an item to an attribute array, rather then * replacing the whole list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST * @param name name of the ldap attribute to append to * @param vals an array of values to add * @return status of addition **/ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods,				const char *name, const char **vals){	return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, (const void **) vals);}/** * Determines the computer account's current KVNO via an LDAP lookup * @param ads An initialized ADS_STRUCT * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. * @return the kvno for the computer account, or -1 in case of a failure. **/uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name){	LDAPMessage *res = NULL;	uint32 kvno = (uint32)-1;      /* -1 indicates a failure */	char *filter;	const char *attrs[] = {"msDS-KeyVersionNumber", NULL};	char *dn_string = NULL;	ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS);	DEBUG(5,("ads_get_kvno: Searching for host %s\n", machine_name));	if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) {		return kvno;	}	ret = ads_search(ads, (void**)(void *)&res, filter, attrs);	SAFE_FREE(filter);	if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) {		DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name));		ads_msgfree(ads, res);		return kvno;	}	dn_string = ads_get_dn(ads, res);	if (!dn_string) {		DEBUG(0,("ads_get_kvno: out of memory.\n"));		ads_msgfree(ads, res);		return kvno;	}	DEBUG(5,("ads_get_kvno: Using: %s\n", dn_string));	ads_memfree(ads, dn_string);	/* ---------------------------------------------------------	 * 0 is returned as a default KVNO from this point on...	 * This is done because Windows 2000 does not support key	 * version numbers.  Chances are that a failure in the next	 * step is simply due to Windows 2000 being used for a	 * domain controller. */	kvno = 0;	if (!ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno)) {		DEBUG(3,("ads_get_kvno: Error Determining KVNO!\n"));		DEBUG(3,("ads_get_kvno: Windows 2000 does not support KVNO's, so this may be normal.\n"));		ads_msgfree(ads, res);		return kvno;	}	/* Success */	DEBUG(5,("ads_get_kvno: Looked Up KVNO of: %d\n", kvno));	ads_msgfree(ads, res);	return kvno;}/** * This clears out all registered spn's for a given hostname * @param ads An initilaized ADS_STRUCT * @param machine_name the NetBIOS name of the computer. * @return 0 upon success, non-zero otherwise. **/ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machine_name){	TALLOC_CTX *ctx;	LDAPMessage *res = NULL;	ADS_MODLIST mods;	const char *servicePrincipalName[1] = {NULL};	ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS);	char *dn_string = NULL;	ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name);	if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) {		DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name));		DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name));		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_SUCH_OBJECT);	}	DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name));	ctx = talloc_init("ads_clear_service_principal_names");	if (!ctx) {		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_MEMORY);	}	if (!(mods = ads_init_mods(ctx))) {		talloc_destroy(ctx);		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_MEMORY);	}	ret = ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);	if (!ADS_ERR_OK(ret)) {		DEBUG(1,("ads_clear_service_principal_names: Error creating strlist.\n"));		ads_msgfree(ads, res);		talloc_destroy(ctx);		return ret;	}	dn_string = ads_get_dn(ads, res);	if (!dn_string) {		talloc_destroy(ctx);		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_MEMORY);	}	ret = ads_gen_mod(ads, dn_string, mods);	ads_memfree(ads,dn_string);	if (!ADS_ERR_OK(ret)) {		DEBUG(1,("ads_clear_service_principal_names: Error: Updating Service Principals for machine %s in LDAP\n",			machine_name));		ads_msgfree(ads, res);		talloc_destroy(ctx);		return ret;	}	ads_msgfree(ads, res);	talloc_destroy(ctx);	return ret;}/** * This adds a service principal name to an existing computer account * (found by hostname) in AD. * @param ads An initialized ADS_STRUCT * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. * @param spn A string of the service principal to add, i.e. 'host' * @return 0 upon sucess, or non-zero if a failure occurs **/ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name, const char *spn){	ADS_STATUS ret;	TALLOC_CTX *ctx;	LDAPMessage *res = NULL;	char *host_spn, *psp1, *psp2, *psp3;	ADS_MODLIST mods;	fstring my_fqdn;	char *dn_string = NULL;	const char *servicePrincipalName[4] = {NULL, NULL, NULL, NULL};	ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name);	if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) {		DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n",			machine_name));		DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principal '%s/%s@%s' has NOT been added.\n",			spn, machine_name, ads->config.realm));		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_SUCH_OBJECT);	}	DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name));	if (!(ctx = talloc_init("ads_add_service_principal_name"))) {		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_MEMORY);	}	name_to_fqdn(my_fqdn, machine_name);	strlower_m(my_fqdn);	if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) {		talloc_destroy(ctx);		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_SUCH_OBJECT);	}	/* Add the extra principal */	psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name);	strupper_m(psp1);	strlower_m(&psp1[strlen(spn)]);	DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name));	servicePrincipalName[0] = psp1;	psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm);	strupper_m(psp2);	strlower_m(&psp2[strlen(spn)]);	DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name));	servicePrincipalName[1] = psp2;	/* Add another principal in case the realm != the DNS domain, so that	 * the KDC doesn't send "server principal unknown" errors to clients	 * which use the DNS name in determining service principal names. */	psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn);	strupper_m(psp3);	strlower_m(&psp3[strlen(spn)]);	if (strcmp(psp2, psp3) != 0) {		DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp3, machine_name));		servicePrincipalName[2] = psp3;	}	if (!(mods = ads_init_mods(ctx))) {		talloc_destroy(ctx);		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_MEMORY);	}	ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);	if (!ADS_ERR_OK(ret)) {		DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));		talloc_destroy(ctx);		ads_msgfree(ads, res);		return ret;	}	dn_string = ads_get_dn(ads, res);	if (!dn_string) {		talloc_destroy(ctx);		ads_msgfree(ads, res);		return ADS_ERROR(LDAP_NO_MEMORY);	}	ret = ads_gen_mod(ads, dn_string, mods);	ads_memfree(ads,dn_string);	if (!ADS_ERR_OK(ret)) {		DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));		talloc_destroy(ctx);		ads_msgfree(ads, res);		return ret;	}	talloc_destroy(ctx);	ads_msgfree(ads, res);	return ret;}/** * adds a machine account to the ADS server * @param ads An intialized ADS_STRUCT * @param machine_name - the NetBIOS machine name of this account. * @param account_type A number indicating the type of account to create * @param org_unit The LDAP path in which to place this account * @return 0 upon success, or non-zero otherwise**/static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name, 				       uint32 account_type,				       const char *org_unit){	ADS_STATUS ret, status;	char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr;	TALLOC_CTX *ctx;	ADS_MODLIST mods;	const char *objectClass[] = {"top", "person", "organizationalPerson",				     "user", "computer", NULL};	const char *servicePrincipalName[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};	char *psp, *psp2, *psp3, *psp4;	unsigned acct_control;	unsigned exists=0;	fstring my_fqdn;	LDAPMessage *res = NULL;	int i, next_spn;	if (!(ctx = talloc_init("ads_add_machine_acct")))		return ADS_ERROR(LDAP_NO_MEMORY);	ret = ADS_ERROR(LDAP_NO_MEMORY);	name_to_fqdn(my_fqdn, machine_name);	status = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name);	if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {		char *dn_string = ads_get_dn(ads, res);		if (!dn_string) {			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,dn_string);		DEBUG(0, ("ads_add_machine_acct: Host account for %s already exists - modifying old account\n",			machine_name));		exists=1;	} else {		char *ou_str = ads_ou_string(ads,org_unit);		if (!ou_str) {			DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n"));			goto done;		}		new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", machine_name, ou_str, 				ads->config.bind_path);		SAFE_FREE(ou_str);	}	if (!new_dn) {		goto done;	}	if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", machine_name)))		goto done;	if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -