summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2001-12-30 10:54:58 +0000
committerAndrew Bartlett <abartlet@samba.org>2001-12-30 10:54:58 +0000
commitf6e6c678ad5338264496de43e9e1ab2fe4a28e64 (patch)
tree21145aeb71e92fb12865142a70a1435a25100da5 /source3
parent3e10f9554ba0c3408be7ac859ec299394c2b0295 (diff)
downloadsamba-f6e6c678ad5338264496de43e9e1ab2fe4a28e64.tar.gz
samba-f6e6c678ad5338264496de43e9e1ab2fe4a28e64.tar.bz2
samba-f6e6c678ad5338264496de43e9e1ab2fe4a28e64.zip
Add a pile of doxygen style comments to various parts of Samba. Many of these
probably will never actually be genearted, but I like the style in any case. Also fix a segfault in 'net rpc' when the login failed and a small memory leak on failure in the auth_info.c code. Andrew Bartlett (This used to be commit 2efae7cc522651c22fb120835bc800645559b63e)
Diffstat (limited to 'source3')
-rw-r--r--source3/auth/auth.c85
-rw-r--r--source3/auth/auth_builtin.c31
-rw-r--r--source3/auth/auth_info.c37
-rw-r--r--source3/auth/auth_unix.c22
-rw-r--r--source3/param/loadparm.c2
-rw-r--r--source3/utils/net_rpc.c274
-rw-r--r--source3/utils/net_rpc_join.c12
7 files changed, 356 insertions, 107 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 710b5f27fb..94927fe96e 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -23,11 +23,18 @@
#include "includes.h"
-/****************************************************************************
- Check user is in correct domain if required
-****************************************************************************/
-
-static BOOL check_domain_match(char *user, char *domain)
+/**
+ * Check user is in correct domain (if required)
+ *
+ * @param user Only used to fill in the debug message
+ *
+ * @param domain The domain to be verified
+ *
+ * @return True if the user can connect with that domain,
+ * False otherwise.
+**/
+
+static BOOL check_domain_match(const char *user, const char *domain)
{
/*
* If we aren't serving to trusted domains, we must make sure that
@@ -46,22 +53,37 @@ static BOOL check_domain_match(char *user, char *domain)
}
}
-/****************************************************************************
- Check a users password, as given in the user-info struct and return various
- interesting details in the server_info struct.
-
- This functions does NOT need to be in a become_root()/unbecome_root() pair
- as it makes the calls itself when needed.
-
- The return value takes precedence over the contents of the server_info
- struct. When the return is other than NT_STATUS_NOPROBLEMO the contents
- of that structure is undefined.
-
-****************************************************************************/
+/**
+ * Check a user's Plaintext, LM or NTLM password.
+ *
+ * Check a user's password, as given in the user_info struct and return various
+ * interesting details in the server_info struct.
+ *
+ * This function does NOT need to be in a become_root()/unbecome_root() pair
+ * as it makes the calls itself when needed.
+ *
+ * The return value takes precedence over the contents of the server_info
+ * struct. When the return is other than NT_STATUS_OK the contents
+ * of that structure is undefined.
+ *
+ * @param user_info Contains the user supplied components, including the passwords.
+ * Must be created with make_user_info() or one of its wrappers.
+ *
+ * @param auth_info Supplies the challanges and some other data.
+ * Must be created with make_auth_info(), and the challanges should be
+ * filled in, either at creation or by calling the challange geneation
+ * function auth_get_challange().
+ *
+ * @param server_info If successful, contains information about the authenticaion,
+ * including a SAM_ACCOUNT struct describing the user.
+ *
+ * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
+ *
+ **/
NTSTATUS check_password(const auth_usersupplied_info *user_info,
- const auth_authsupplied_info *auth_info,
- auth_serversupplied_info **server_info)
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
@@ -92,6 +114,11 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length);
#endif
+ /* This needs to be sorted: If it doesn't match, what should we do? */
+ if (!check_domain_match(user_info->smb_name.str, user_info->domain.str)) {
+ return NT_STATUS_LOGON_FAILURE;
+ }
+
for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next)
{
nt_status = auth_method->auth(auth_method->private_data, user_info, auth_info, server_info);
@@ -108,12 +135,6 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
}
}
- /* This needs to be sorted: If it doesn't match, what should we do? */
- if (!check_domain_match(user_info->smb_name.str, user_info->domain.str)) {
- return NT_STATUS_LOGON_FAILURE;
- }
-
-
/* This is one of the few places the *relies* (rather than just sets defaults
on the value of lp_security(). This needs to change. A new paramater
perhaps? */
@@ -158,10 +179,16 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
}
-/****************************************************************************
- Squash an NT_STATUS return in line with requirements for unauthenticated
- connections. (session setups in particular)
-****************************************************************************/
+/**
+ * Squash an NT_STATUS in line with security requirements.
+ * In an attempt to avoid giving the whole game away when users
+ * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and
+ * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations
+ * (session setups in particular).
+ *
+ * @param nt_status NTSTATUS input for squashing.
+ * @return the 'squashed' nt_status
+ **/
NTSTATUS nt_status_squash(NTSTATUS nt_status)
{
diff --git a/source3/auth/auth_builtin.c b/source3/auth/auth_builtin.c
index 2bba36f754..8f283fd856 100644
--- a/source3/auth/auth_builtin.c
+++ b/source3/auth/auth_builtin.c
@@ -21,10 +21,13 @@
#include "includes.h"
-/****************************************************************************
- Check for a guest logon (username = "") and if so create the required
- structure.
-****************************************************************************/
+/**
+ * Return a guest logon for guest users (username = "")
+ *
+ * Typically used as the first module in the auth chain, this allows
+ * guest logons to be delt with in one place. Non-gust logons 'fail'
+ * and pass onto the next module.
+ **/
static NTSTATUS check_guest_security(void *my_private_data,
const auth_usersupplied_info *user_info,
@@ -45,6 +48,7 @@ static NTSTATUS check_guest_security(void *my_private_data,
return nt_status;
}
+/* Guest modules initialisation */
BOOL auth_init_guest(auth_methods **auth_method)
{
if (!make_auth_methods(auth_method)) {
@@ -55,9 +59,18 @@ BOOL auth_init_guest(auth_methods **auth_method)
return True;
}
-/****************************************************************************
- Return an error based on username
-****************************************************************************/
+/**
+ * Return an error based on username
+ *
+ * This function allows the testing of obsure errors, as well as the generation
+ * of NT_STATUS -> DOS error mapping tables.
+ *
+ * This module is of no value to end-users.
+ *
+ * The password is ignored.
+ *
+ * @return An NTSTATUS value based on the username
+ **/
static NTSTATUS check_name_to_ntstatus_security(void *my_private_data,
const auth_usersupplied_info *user_info,
@@ -78,6 +91,7 @@ static NTSTATUS check_name_to_ntstatus_security(void *my_private_data,
return nt_status;
}
+/** Module initailisation function */
BOOL auth_init_name_to_ntstatus(auth_methods **auth_method)
{
if (!make_auth_methods(auth_method)) {
@@ -88,3 +102,6 @@ BOOL auth_init_name_to_ntstatus(auth_methods **auth_method)
return True;
}
+
+
+
diff --git a/source3/auth/auth_info.c b/source3/auth/auth_info.c
index cc13d5a8b9..bdd490d3ef 100644
--- a/source3/auth/auth_info.c
+++ b/source3/auth/auth_info.c
@@ -21,6 +21,8 @@
#include "includes.h"
+/** List of various built-in authenticaion modules */
+
const struct auth_init_function builtin_auth_init_functions[] = {
{ "guest", auth_init_guest },
{ "rhosts", auth_init_rhosts },
@@ -38,6 +40,25 @@ const struct auth_init_function builtin_auth_init_functions[] = {
};
/***************************************************************************
+ Free a linked list of auth methods
+***************************************************************************/
+
+static void free_auth_methods_list(auth_methods **list)
+{
+ if (list != NULL) {
+ while (*list) {
+ auth_methods *old_head = *list;
+ if ((*list)->free_private_data) {
+ (*list)->free_private_data(&((*list)->private_data));
+ }
+ DLIST_REMOVE(*list, *list);
+ SAFE_FREE(old_head);
+ }
+
+ }
+}
+
+/***************************************************************************
Make a auth_info struct
***************************************************************************/
@@ -104,7 +125,10 @@ static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **
}
}
- make_auth_info_list(auth_info, list);
+ if (!make_auth_info_list(auth_info, list)) {
+ free_auth_methods_list(&list);
+ return False;
+ }
return True;
}
@@ -210,17 +234,8 @@ BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8])
void free_auth_info(auth_authsupplied_info **auth_info)
{
- auth_methods *list;
if (*auth_info != NULL) {
- list = (*auth_info)->auth_method_list;
- while (list) {
- auth_methods *old_head = list;
- if (list->free_private_data) {
- list->free_private_data(&(list->private_data));
- }
- DLIST_REMOVE(list, list);
- SAFE_FREE(old_head);
- }
+ free_auth_methods_list(&(*auth_info)->auth_method_list);
data_blob_free(&(*auth_info)->challenge);
ZERO_STRUCT(**auth_info);
diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c
index d134ce6909..2e753cb29c 100644
--- a/source3/auth/auth_unix.c
+++ b/source3/auth/auth_unix.c
@@ -21,11 +21,11 @@
#include "includes.h"
-/****************************************************************************
-update the encrypted smbpasswd file from the plaintext username and password
-
-this ugly hack needs to die, but not quite yet...
-*****************************************************************************/
+/**
+ * update the encrypted smbpasswd file from the plaintext username and password
+ *
+ * this ugly hack needs to die, but not quite yet, I think people still use it...
+ **/
static BOOL update_smbpassword_file(char *user, char *password)
{
SAM_ACCOUNT *sampass = NULL;
@@ -77,10 +77,11 @@ static BOOL update_smbpassword_file(char *user, char *password)
}
-/****************************************************************************
-check if a username/password is OK assuming the password
-in PLAIN TEXT
-****************************************************************************/
+/** Check a plaintext username/password
+ *
+ * Cannot deal with an encrupted password in any manner whatsoever,
+ * unless the account has a null password.
+ **/
NTSTATUS check_unix_security(void *my_private_data,
const auth_usersupplied_info *user_info,
@@ -93,6 +94,9 @@ NTSTATUS check_unix_security(void *my_private_data,
become_root();
pass = Get_Pwnam(user_info->internal_username.str);
+
+ /** This call assumes a ASCII password, no charset transformation is
+ done. We may need to revisit this **/
nt_status = pass_check(pass,
pass ? pass->pw_name : user_info->internal_username.str,
(char *)user_info->plaintext_password.data,
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 335995b0dd..d1448df8d3 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -3862,7 +3862,7 @@ void get_private_directory(pstring privdir)
Is netbios alias or name
*****************************************************************/
-BOOL is_netbios_alias_or_name(char *name)
+BOOL is_netbios_alias_or_name(const char *name)
{
char **netbios_aliases = lp_netbios_aliases();
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 97a1a1d342..b98cae37b6 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -21,9 +21,32 @@
#include "includes.h"
#include "../utils/net.h"
-
+/**
+ * @file net_rpc.c
+ *
+ * @brief RPC based subcommands for the 'net' utility.
+ *
+ * This file should contain much of the functionality that used to
+ * be found in rpcclient, execpt that the commands should change
+ * less often, and the fucntionality should be sane (the user is not
+ * expected to know a rid/sid before they conduct an operation etc.)
+ *
+ * @todo Perhaps eventually these should be split out into a number
+ * of files, as this could get quite big.
+ **/
+
+
+/* A function of this type is passed to the 'run_rpc_command' wrapper */
typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **);
+/**
+ * Many of the RPC functions need the domain sid. This function gets
+ * it at the start of every run
+ *
+ * @param cli A cli_state already connected to the remote machine
+ *
+ * @return The Domain SID of the remote machine.
+ */
static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
{
@@ -80,6 +103,17 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
exit(1);
}
+/**
+ * Run a single RPC command, from start to finish.
+ *
+ * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
+ * @param conn_flag a NET_FLAG_ combination. Passed to
+ * net_make_ipc_connection.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ * @return A shell status integer (0 for success)
+ */
static int run_rpc_command(const char *pipe_name, int conn_flags,
rpc_command_fn fn,
@@ -88,7 +122,14 @@ static int run_rpc_command(const char *pipe_name, int conn_flags,
struct cli_state *cli = net_make_ipc_connection(conn_flags);
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
- DOM_SID *domain_sid = net_get_remote_domain_sid(cli);
+ DOM_SID *domain_sid;
+
+ if (!cli) {
+ return -1;
+ }
+
+ domain_sid = net_get_remote_domain_sid(cli);
+
/* Create mem_ctx */
if (!(mem_ctx = talloc_init())) {
@@ -113,54 +154,25 @@ static int run_rpc_command(const char *pipe_name, int conn_flags,
return (!NT_STATUS_IS_OK(nt_status));
}
-static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
- POLICY_HND connect_pol, domain_pol, user_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- const char *acct_name;
- uint16 acb_info;
- uint32 unknown, user_rid;
-
- if (argc != 1) {
- d_printf("Usage: net rpc user add username\n");
- return NT_STATUS_OK;
- }
-
- acct_name = argv[0];
-
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Create domain user */
- acb_info = ACB_NORMAL;
- unknown = 0xe005000b; /* No idea what this is - a permission mask? */
+/****************************************************************************/
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
- &user_pol, &user_rid);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
- done:
- return result;
-}
+/**
+ * Force a change of the trust acccount password.
+ *
+ * All paramaters are provided by the run_rpc_command funcion, except for
+ * argc, argv which are passes through.
+ *
+ * @param domain_sid The domain sid aquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv) {
@@ -168,12 +180,46 @@ static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cl
return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
}
+/**
+ * Force a change of the trust acccount password.
+ *
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+
static int rpc_changetrustpw(int argc, const char **argv)
{
return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
argc, argv);
}
+
+/****************************************************************************/
+
+
+/**
+ * Join a domain, the old way.
+ *
+ * This uses 'machinename' as the inital password, and changes it.
+ *
+ * The password should be created with 'server manager' or eqiv first.
+ *
+ * All paramaters are provided by the run_rpc_command funcion, except for
+ * argc, argv which are passes through.
+ *
+ * @param domain_sid The domain sid aquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
+
static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv) {
@@ -188,12 +234,29 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
}
+/**
+ * Join a domain, the old way.
+ *
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+
static int rpc_join_oldstyle(int argc, const char **argv)
{
return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
argc, argv);
}
+/**
+ * Basic usage function for 'net rpc join'
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ **/
+
static int rpc_join_usage(int argc, const char **argv)
{
d_printf(" net rpc join \t to join a domain with admin username & password\n");
@@ -201,6 +264,16 @@ static int rpc_join_usage(int argc, const char **argv)
return -1;
}
+/**
+ * 'net rpc join' entrypoint.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * Main 'net_rpc_join()' (where the admain username/password is used) is
+ * in net_rpc_join.c
+ **/
+
static int rpc_join(int argc, const char **argv)
{
struct functable func[] = {
@@ -215,18 +288,111 @@ static int rpc_join(int argc, const char **argv)
return net_run_function(argc, argv, func, rpc_join_usage);
}
+
+/****************************************************************************/
+
+
+/**
+ * Add a new user to a remote RPC server
+ *
+ * All paramaters are provided by the run_rpc_command funcion, except for
+ * argc, argv which are passes through.
+ *
+ * @param domain_sid The domain sid aquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
+
+static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv) {
+
+ POLICY_HND connect_pol, domain_pol, user_pol;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ const char *acct_name;
+ uint16 acb_info;
+ uint32 unknown, user_rid;
+
+ if (argc != 1) {
+ d_printf("Usage: net rpc user add username\n");
+ return NT_STATUS_OK;
+ }
+
+ acct_name = argv[0];
+
+ /* Get sam policy handle */
+
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Get domain policy handle */
+
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Create domain user */
+
+ acb_info = ACB_NORMAL;
+ unknown = 0xe005000b; /* No idea what this is - a permission mask? */
+
+ result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
+ acct_name, acb_info, unknown,
+ &user_pol, &user_rid);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ return result;
+}
+
+/**
+ * Add a new user to a remote RPC server
+ *
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+
static int rpc_user_add(int argc, const char **argv)
{
return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals,
argc, argv);
}
+/**
+ * Basic usage function for 'net rpc join'
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ **/
+
static int rpc_user_usage(int argc, const char **argv)
{
d_printf(" net rpc user add \t to add a user\n");
return -1;
}
+/**
+ * 'net rpc user' entrypoint.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ **/
+
static int rpc_user(int argc, const char **argv)
{
struct functable func[] = {
@@ -241,6 +407,13 @@ static int rpc_user(int argc, const char **argv)
return net_run_function(argc, argv, func, rpc_user_usage);
}
+/**
+ * Basic usage function for 'net rpc join'
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ **/
+
int net_rpc_usage(int argc, const char **argv)
{
d_printf(" net rpc join \tto join a domain \n");
@@ -249,6 +422,13 @@ int net_rpc_usage(int argc, const char **argv)
return -1;
}
+/**
+ * 'net rpc user' entrypoint.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ **/
+
int net_rpc(int argc, const char **argv)
{
struct functable func[] = {
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 16b0ccbaa8..5f5117c9bc 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -36,9 +36,15 @@
goto done; \
}
-/*********************************************************
-Join a domain using the administrator username and password
-**********************************************************/
+/**
+ * Join a domain using the administrator username and password
+ *
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped. Currently not used.
+ * @return A shell status integer (0 for success)
+ *
+ **/
int net_rpc_join(int argc, const char **argv)
{