s3-lib: Do not set an empty string in split_domain_user()
[samba.git] / source3 / rpc_server / wkssvc / srv_wkssvc_nt.c
index 633aa1336039bee164fa01bd37cffa65b6519e28..25233e5b07e40df5c81d9e50be1d8f7d85e07f65 100644 (file)
@@ -32,6 +32,7 @@
 #include "session.h"
 #include "smbd/smbd.h"
 #include "auth.h"
+#include "krb5_env.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
@@ -182,8 +183,8 @@ static struct dom_usr *get_domain_userlist(TALLOC_CTX *mem_ctx)
        }
 
        for (i=num_users=0; i<num_sessions; i++) {
-               if (!session_list[i].username
-                   || !session_list[i].remote_machine) {
+               if (session_list[i].username[0] == '\0' ||
+                   session_list[i].remote_machine[0] == '\0') {
                        continue;
                }
                p = strpbrk(session_list[i].remote_machine, "./");
@@ -260,8 +261,8 @@ static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx)
        }
 
        info100->platform_id     = PLATFORM_ID_NT;      /* unknown */
-       info100->version_major   = lp_major_announce_version();
-       info100->version_minor   = lp_minor_announce_version();
+       info100->version_major   = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
+       info100->version_minor   = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
 
        info100->server_name = talloc_asprintf_strupper_m(
                info100, "%s", lp_netbios_name());
@@ -289,8 +290,8 @@ static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx)
        }
 
        info101->platform_id     = PLATFORM_ID_NT;      /* unknown */
-       info101->version_major   = lp_major_announce_version();
-       info101->version_minor   = lp_minor_announce_version();
+       info101->version_major   = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
+       info101->version_minor   = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
 
        info101->server_name = talloc_asprintf_strupper_m(
                info101, "%s", lp_netbios_name());
@@ -320,8 +321,8 @@ static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx)
        }
 
        info102->platform_id     = PLATFORM_ID_NT;      /* unknown */
-       info102->version_major   = lp_major_announce_version();
-       info102->version_minor   = lp_minor_announce_version();
+       info102->version_major   = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
+       info102->version_minor   = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
 
        info102->server_name = talloc_asprintf_strupper_m(
                info102, "%s", lp_netbios_name());
@@ -404,7 +405,7 @@ WERROR _wkssvc_NetWkstaSetInfo(struct pipes_struct *p,
                               struct wkssvc_NetWkstaSetInfo *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -505,7 +506,7 @@ static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1(
 
        pwd_server = "";
 
-       if ((pwd_tmp = talloc_strdup(ctr1->user1, lp_passwordserver()))) {
+       if ((pwd_tmp = talloc_strdup(ctr1->user1, lp_password_server()))) {
                /* The configured password server is a full DNS name but
                 * for the logon server we need to return just the first
                 * component (machine name) of it in upper-case */
@@ -578,7 +579,9 @@ WERROR _wkssvc_NetWkstaEnumUsers(struct pipes_struct *p,
                }
                r->out.info->level = r->in.info->level;
                *r->out.entries_read = r->out.info->ctr.user0->entries_read;
-               *r->out.resume_handle = 0;
+               if (r->out.resume_handle != NULL) {
+                       *r->out.resume_handle = 0;
+               }
                break;
        case 1:
                r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx);
@@ -587,7 +590,9 @@ WERROR _wkssvc_NetWkstaEnumUsers(struct pipes_struct *p,
                }
                r->out.info->level = r->in.info->level;
                *r->out.entries_read = r->out.info->ctr.user1->entries_read;
-               *r->out.resume_handle = 0;
+               if (r->out.resume_handle != NULL) {
+                       *r->out.resume_handle = 0;
+               }
                break;
        default:
                return WERR_UNKNOWN_LEVEL;
@@ -603,7 +608,7 @@ WERROR _wkssvc_NetrWkstaUserGetInfo(struct pipes_struct *p,
                                    struct wkssvc_NetrWkstaUserGetInfo *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -614,7 +619,7 @@ WERROR _wkssvc_NetrWkstaUserSetInfo(struct pipes_struct *p,
                                    struct wkssvc_NetrWkstaUserSetInfo *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -625,7 +630,7 @@ WERROR _wkssvc_NetWkstaTransportEnum(struct pipes_struct *p,
                                     struct wkssvc_NetWkstaTransportEnum *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -636,7 +641,7 @@ WERROR _wkssvc_NetrWkstaTransportAdd(struct pipes_struct *p,
                                     struct wkssvc_NetrWkstaTransportAdd *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -647,7 +652,7 @@ WERROR _wkssvc_NetrWkstaTransportDel(struct pipes_struct *p,
                                     struct wkssvc_NetrWkstaTransportDel *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -658,7 +663,7 @@ WERROR _wkssvc_NetrUseAdd(struct pipes_struct *p,
                          struct wkssvc_NetrUseAdd *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -669,7 +674,7 @@ WERROR _wkssvc_NetrUseGetInfo(struct pipes_struct *p,
                              struct wkssvc_NetrUseGetInfo *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -680,7 +685,7 @@ WERROR _wkssvc_NetrUseDel(struct pipes_struct *p,
                          struct wkssvc_NetrUseDel *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -691,7 +696,7 @@ WERROR _wkssvc_NetrUseEnum(struct pipes_struct *p,
                           struct wkssvc_NetrUseEnum *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -702,7 +707,7 @@ WERROR _wkssvc_NetrMessageBufferSend(struct pipes_struct *p,
                                     struct wkssvc_NetrMessageBufferSend *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -713,7 +718,7 @@ WERROR _wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct *p,
                                            struct wkssvc_NetrWorkstationStatisticsGet *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -724,7 +729,7 @@ WERROR _wkssvc_NetrLogonDomainNameAdd(struct pipes_struct *p,
                                      struct wkssvc_NetrLogonDomainNameAdd *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -735,7 +740,7 @@ WERROR _wkssvc_NetrLogonDomainNameDel(struct pipes_struct *p,
                                      struct wkssvc_NetrLogonDomainNameDel *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -746,7 +751,7 @@ WERROR _wkssvc_NetrJoinDomain(struct pipes_struct *p,
                              struct wkssvc_NetrJoinDomain *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -757,7 +762,7 @@ WERROR _wkssvc_NetrUnjoinDomain(struct pipes_struct *p,
                                struct wkssvc_NetrUnjoinDomain *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -768,7 +773,7 @@ WERROR _wkssvc_NetrRenameMachineInDomain(struct pipes_struct *p,
                                         struct wkssvc_NetrRenameMachineInDomain *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -779,7 +784,7 @@ WERROR _wkssvc_NetrValidateName(struct pipes_struct *p,
                                struct wkssvc_NetrValidateName *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -790,7 +795,7 @@ WERROR _wkssvc_NetrGetJoinInformation(struct pipes_struct *p,
                                      struct wkssvc_NetrGetJoinInformation *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -801,7 +806,7 @@ WERROR _wkssvc_NetrGetJoinableOus(struct pipes_struct *p,
                                  struct wkssvc_NetrGetJoinableOus *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -818,6 +823,9 @@ WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
        char *admin_account = NULL;
        WERROR werr;
        struct security_token *token = p->session_info->security_token;
+       NTSTATUS status;
+       DATA_BLOB session_key;
+       bool ok;
 
        if (!r->in.domain_name) {
                return WERR_INVALID_PARAM;
@@ -840,17 +848,29 @@ WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
                return WERR_NOT_SUPPORTED;
        }
 
+       status = session_extract_session_key(p->session_info,
+                                            &session_key,
+                                            KEY_USE_16BYTES);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("_wkssvc_NetrJoinDomain2: no session key %s\n",
+                       nt_errstr(status)));
+               return WERR_NO_USER_SESSION_KEY;
+       }
+
        werr = decode_wkssvc_join_password_buffer(
                p->mem_ctx, r->in.encrypted_password,
-               &p->session_info->session_key, &cleartext_pwd);
+               &session_key, &cleartext_pwd);
        if (!W_ERROR_IS_OK(werr)) {
                return werr;
        }
 
-       split_domain_user(p->mem_ctx,
-                         r->in.admin_account,
-                         &admin_domain,
-                         &admin_account);
+       ok = split_domain_user(p->mem_ctx,
+                              r->in.admin_account,
+                              &admin_domain,
+                              &admin_account);
+       if (!ok) {
+               return WERR_NOMEM;
+       }
 
        werr = libnet_init_JoinCtx(p->mem_ctx, &j);
        if (!W_ERROR_IS_OK(werr)) {
@@ -867,7 +887,9 @@ WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
        j->in.msg_ctx           = p->msg_ctx;
 
        become_root();
+       setenv(KRB5_ENV_CCNAME, "MEMORY:_wkssvc_NetrJoinDomain2", 1);
        werr = libnet_Join(p->mem_ctx, j);
+       unsetenv(KRB5_ENV_CCNAME);
        unbecome_root();
 
        if (!W_ERROR_IS_OK(werr)) {
@@ -893,6 +915,9 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
        char *admin_account = NULL;
        WERROR werr;
        struct security_token *token = p->session_info->security_token;
+       NTSTATUS status;
+       DATA_BLOB session_key;
+       bool ok;
 
        if (!r->in.account || !r->in.encrypted_password) {
                return WERR_INVALID_PARAM;
@@ -906,17 +931,29 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
                return WERR_ACCESS_DENIED;
        }
 
+       status = session_extract_session_key(p->session_info,
+                                            &session_key,
+                                            KEY_USE_16BYTES);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("_wkssvc_NetrUnjoinDomain2: no session key %s\n",
+                       nt_errstr(status)));
+               return WERR_NO_USER_SESSION_KEY;
+       }
+
        werr = decode_wkssvc_join_password_buffer(
                p->mem_ctx, r->in.encrypted_password,
-               &p->session_info->session_key, &cleartext_pwd);
+               &session_key, &cleartext_pwd);
        if (!W_ERROR_IS_OK(werr)) {
                return werr;
        }
 
-       split_domain_user(p->mem_ctx,
-                         r->in.account,
-                         &admin_domain,
-                         &admin_account);
+       ok = split_domain_user(p->mem_ctx,
+                              r->in.account,
+                              &admin_domain,
+                              &admin_account);
+       if (!ok) {
+               return WERR_NOMEM;
+       }
 
        werr = libnet_init_UnjoinCtx(p->mem_ctx, &u);
        if (!W_ERROR_IS_OK(werr)) {
@@ -933,7 +970,9 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
        u->in.msg_ctx           = p->msg_ctx;
 
        become_root();
+       setenv(KRB5_ENV_CCNAME, "MEMORY:_wkssvc_NetrUnjoinDomain2", 1);
        werr = libnet_Unjoin(p->mem_ctx, u);
+       unsetenv(KRB5_ENV_CCNAME);
        unbecome_root();
 
        if (!W_ERROR_IS_OK(werr)) {
@@ -953,6 +992,7 @@ WERROR _wkssvc_NetrRenameMachineInDomain2(struct pipes_struct *p,
                                          struct wkssvc_NetrRenameMachineInDomain2 *r)
 {
        /* for now just return not supported */
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -963,7 +1003,7 @@ WERROR _wkssvc_NetrValidateName2(struct pipes_struct *p,
                                 struct wkssvc_NetrValidateName2 *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -974,7 +1014,7 @@ WERROR _wkssvc_NetrGetJoinableOus2(struct pipes_struct *p,
                                   struct wkssvc_NetrGetJoinableOus2 *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -985,7 +1025,7 @@ WERROR _wkssvc_NetrAddAlternateComputerName(struct pipes_struct *p,
                                            struct wkssvc_NetrAddAlternateComputerName *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -996,7 +1036,7 @@ WERROR _wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct *p,
                                               struct wkssvc_NetrRemoveAlternateComputerName *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -1007,7 +1047,7 @@ WERROR _wkssvc_NetrSetPrimaryComputername(struct pipes_struct *p,
                                          struct wkssvc_NetrSetPrimaryComputername *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
 
@@ -1018,6 +1058,6 @@ WERROR _wkssvc_NetrEnumerateComputerNames(struct pipes_struct *p,
                                          struct wkssvc_NetrEnumerateComputerNames *r)
 {
        /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }