Jump to content


Photo

Problem adding domain, then users via API

v600 api

  • Please log in to reply
4 replies to this topic

#1 Mark Wiggins

Mark Wiggins
  • Members
  • 3 posts

Posted 07 December 2011 - 05:15 PM

Hello,

The company that I work for is thinking about switching our email security over from Postini to Barracuda. We have a v600 setup and I have been developing scripts to pull our domains, users and whitelist/blacklist addresses from Postini, and add them to the Barracuda via the API.

I have successfully added domains, added users, added whitelist entries, etc, as separate scripts. I run into a problem though, when I attempt to combine them all into one script. Here's what happens: the script successfully adds a domain, then successfully tweaks a few settings (Auth Type and POP Server). Then it attempts to add users, and it fails with this error on each user: Unable to validate account. (code: 421)

The thing is, if I add the domain to the Barracuda manually, through the web gui, then run this exact same script, only with the domain add/configure part commented out, it'll add the users just fine. Same code, same parsing, same email addresses. Only difference is the domain was previously added to the Barracuda. Seems to me like maybe I can't add users immediately after adding a domain. Perhaps I have to wait a few minutes for the config to save/reload? I even tried adding a config.reload request to my script in between adding/configuring the domain and adding the users, but that didn't fix it.

Anybody have any ideas on what might be going wrong and how I can fix it?

Thank you.

#2 Mark Wiggins

Mark Wiggins
  • Members
  • 3 posts

Posted 19 January 2012 - 04:33 PM

Just thought I'd update this thread. I worked with a Barracuda Support Rep and he was able to determine that the problem was due to a bug in the firmware. He applied a couple of patches and it resolved the issue.

#3 FranHis

FranHis
  • Members
  • 4 posts

Posted 01 May 2013 - 10:01 PM

I'm trying to get our domains/users into Barracua 600 using the API, and I'm having a lot of problem figuring our PHP xmlrpc and the Barracuda variables.
I'd welcome sample scripts. PHP or Perl OK with me.

/Fran

#4 Mark Wiggins

Mark Wiggins
  • Members
  • 3 posts

Posted 01 May 2013 - 10:35 PM

I'm trying to get our domains/users into Barracua 600 using the API, and I'm having a lot of problem figuring our PHP xmlrpc and the Barracuda variables.
I'd welcome sample scripts. PHP or Perl OK with me.

/Fran


Hi Fran, I do all of my barracuda scripts in PHP. Here are some examples. I place each of my XML docs in a seperate file and include them as needed, but I'll just paste the code here.

Add Domain:

$xml = '<?XML version="1.0" encoding="UTF8"?>
<methodCall>
	<methodName>domain.add</methodName>
	<params>
		<param>
			<value>
				<struct>
					<member>
						<name>domain</name>
						<value>
							<string><![CDATA['.$domain.']]></string>
						</value>
					</member>
				</struct>
			</value>
		</param>
	</params>
</methodCall>';

I don't know why the code tag is exaggerating my indentions, but oh well. :-)

I also have this code in a seperate file and include it as needed:

$host = 'your.barracuda.domain';
$port = 443;
$url = '/cgi-mod/api.cgi?password=yourpassowrd';

$header = "POST $url HTTP/1.0\r\n";
$header .= "Connection: Keep-Alive\r\n";
$header .= "Content-type: text/xml\r\n";
$header .= 'Content-Length: '. strlen($xml)."\r\n\r\n";
$header .= "xml=$xml";

And finally, I make the connection, send the data and capture the response:

$post = fsockopen("ssl://$host", $port, $errno, $errstr, 30); // Open a connection.

if ($post) {
						
	fputs($post, $header); // POST the data.
	
	$response = NULL; // Initializing a var to store the response
	
	while (TRUE !== feof($post)) {
	
		$line = fgets($post, 1024); // Getting each line of the response.
		
		$response .= $line; // Store each line for parsing with php
	
	}
	
	fclose($post);
	
	// Remove http headers and trim whitespace:
	$start = strpos($response, "\r\n\r\n");
	$xml_response = substr($response, $start);
	$xml_response = trim($xml_response);
	
	if ('' == $xml_response) {
					
   	   // YOUR ERROR HANDLING HERE
		
	} else {
	
		// Parse the XML document to an object:
		$response_xml = new SimpleXMLElement($xml_response, LIBXML_NOCDATA);
		
		// Convert the object to an array:
		$response_array = objectToArray($response_xml);
		
		// If the domain was added successfully:
		if (in_multi_array('200: OK', $response_array)) {
			
	   	 // SUCCESS!
			
		} else {
			
		   // Add domain to Barracuda Failed!
		   // YOUR ERROR HANDLING HERE
			
		}
	
	}
	
} else {
						
	// connection error
	// YOUR ERROR HANDLING HERE
	
}

I use a couple of custom functions to parse the result. You certainly don't have to convert the XML object to an array; I'm just more comfortable working with arrays than objects. (Note: I didn't write these, I just googled them up)

Custom Functions:
// Convert an object to an array (single or multidimensional):
function objectToArray($d) {
	
	if (is_object($d)) {
		
		$d = get_object_vars($d); // Gets the properties of the given object with get_object_vars function:
		
	}
	
	if (is_array($d)) {

		return array_map(__FUNCTION__, $d); // Return array converted to object using __FUNCTION__ (Magic constant) for recursive call:
		
	} else {

		return $d; // Return array
	
	}

}

// A version of in_array that will search a multi-dimensional array:
function in_multi_array($needle, $haystack) {
	
	foreach ($haystack as $pos => $value) {
		
		if (is_array($value)) {
			
			if (in_multi_array($needle, $value)) {return TRUE;}
			
		} else {
			
			if ($value == $needle) {return TRUE;}
			
		}
		
	}
	
	return FALSE;
	
}


#5 Mark Wiggins

Mark Wiggins
  • Members
  • 3 posts

Posted 01 May 2013 - 10:43 PM

And here are some more of my XML files:

Add User:
$xml = '<?XML version="1.0" encoding="UTF8"?>
<methodCall>
	<methodName>user.create</methodName>
	<params>
		<param>
			<value>
				<struct>
					<member>
						<name>user</name>
						<value>
							<string><![CDATA['.$user.']]></string>
						</value>
					</member>
				</struct>
			</value>
		</param>
	</params>
</methodCall>';

Set Auth Type (for domain):
$xml = '<?XML version="1.0" encoding="UTF8"?>
<methodCall>
	<methodName>config.set</methodName>
	<params>
		<param>
			<value>
				<struct>
					<member>
						<name>auth_type</name>
						<value>
							<string><![CDATA['.$auth_type.']]></string>
						</value>
					</member>
					<member>
						<name>auth_pop_server</name>
						<value>
							<string><![CDATA['.$auth_server.']]></string>
						</value>
					</member>
					<member>
						<name>mta_relay_advanced_host</name>
						<value>
							<string><![CDATA['.$dest_server.']]></string>
						</value>
					</member>
					<member>
						<name>path</name>
						<value>
							<string><![CDATA['.$domain.']]></string>
						</value>
					</member>
					<member>
						<name>type</name>
						<value>
							<string><![CDATA[domain]]></string>
						</value>
					</member>
				</struct>
			</value>
		</param>
	</params>
</methodCall>';

Reload Config (I always do this after running my Auth Type script above. It's neccessary for your user to validate correclty):
$xml = '<?XML version="1.0" encoding="UTF8"?>
<methodCall>
	<methodName>config.reload</methodName>
	<params>
		<param>
			<value>
				<struct/>
			</value>
		</param>
	</params>
</methodCall>';

And I always do sleep(5); after reloading the config

------
I have quite a a few more. If you'd like help with something specific let me know and I'll help if I can.